一、Redis主从同步

  1.什么是主从同步

    主库:只负责写数据

    从库:只负责读数据(从库手动,配置文件配置)

    主库只要发生更改,数据就会同步到从库

  2.主从同步原理

  1. 副本库通过slaveof 127.0.0.1 6379命令,连接主库,并发送SYNC给主库
  2. 主库收到SYNC,会立即触发BGSAVE,后台保存RDB,发送给副本库
  3. 副本库接收后会应用RDB快照
  4. 主库会陆续将中间产生的新的操作,保存并发送给副本库
  5. 到此,我们主复制集就正常工作了
  6. 再此以后,主库只要发生新的操作,都会以命令传播的形式自动发送给副本库
  7. 所有复制相关信息,从info信息中都可以查到.即使重启任何节点,他的主从关系依然都在
  8. 如果发生主从关系断开时,从库数据没有任何损坏,在下次重连之后,从库发送PSYNC给主库
  9. 主库只会将从库缺失部分的数据同步给从库应用,达到快速恢复主从的目的

  3.主从复制存在的问题

    主从复制,主节点发生故障,需要做故障转移,可以手动转移:让其中一个slave变成master(哨兵)

    主从复制,只能主写数据库,所以写的能力和存储能力有限(集群)

 

原理

  1.多个sentinel(哨兵)发现并确认master有问题

  2.选举出一个sentinel作为领导

  3.选取一个slave作为新的master

  4.通知其余slave成为新的master的slave

  5.通知客户端主从变化

  6.等待老的master复活成为新master的slave

 

 

 

 

 二、搭建主从,配置哨兵

1.Docker拉取CentOS容器,作为本机

docker run -dit --name centos01 -p 6379:6379 -p 6380:6380 -p 6381:6381 -p 26379:26379 -p 26380:26380 -p 26381:26381 centos:7.9.2009

2.进入容器

docker exec -it centos01 bash

3.安装redis

# 1.前往用户根目录
cd ~

# 2.更换yum源,下载redis-5.0.7
curl -o /etc/yum.repos.d/CentOS-Base.repo https://mirrors.aliyun.com/repo/Centos-7.repo

# 安装需要的依赖
yum install gcc vim wget make -y
wget http://download.redis.io/releases/redis-5.0.7.tar.gz

# 觉得安装慢的可以先下载下来,然后复制进去
docker cp /mnt/d/X_Settings/redis/redis-5.0.7.tar.gz centos01:/root/

# 3.解压安装包
tar -xzf redis-5.0.7.tar.gz

# 4.进入目标文件
cd redis-5.0.7


# 5.编译安装
make && make install

# 如果出现:[Errno 256] No more mirrors to try 错误
yum clean all
yum makecache

# 6.复制环境到指定路径完成安装
cp -r ~/redis-5.0.7 /usr/local/redis


# 7.建立软连接
ln -s /usr/local/redis/src/redis-server /usr/bin/redis-server
ln -s /usr/local/redis/src/redis-cli /usr/bin/redis-cli
ln -s /usr/local/redis/src/redis-sentinel /usr/bin/redis-sentinel

# 配置文件
vim /usr/local/redis/redis.conf
# 修改 daemonize yes

# 8.后台运行redis
cd /usr/local/redis
redis-server &

# ctrl + c 停止

# 9.测试redis环境
redis-cli
# ctrl + c 停止

# 10.关闭redis服务
pkill -f redis -9

删除#开头和空行后的redis.conf

bind 127.0.0.1
protected-mode yes
port 6379
tcp-backlog 511
timeout 0
tcp-keepalive 300
daemonize no
supervised no
pidfile /var/run/redis_6379.pid
loglevel notice
logfile ""
databases 16
always-show-logo yes
save 900 1
save 300 10
save 60 10000
stop-writes-on-bgsave-error yes
rdbcompression yes
rdbchecksum yes
dbfilename dump.rdb
dir ./
replica-serve-stale-data yes
replica-read-only yes
repl-diskless-sync no
repl-diskless-sync-delay 5
repl-disable-tcp-nodelay no
replica-priority 100
lazyfree-lazy-eviction no
lazyfree-lazy-expire no
lazyfree-lazy-server-del no
replica-lazy-flush no
appendonly no
appendfilename "appendonly.aof"
appendfsync everysec
no-appendfsync-on-rewrite no
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb
aof-load-truncated yes
aof-use-rdb-preamble yes
lua-time-limit 5000
slowlog-log-slower-than 10000
slowlog-max-len 128
latency-monitor-threshold 0
notify-keyspace-events ""
hash-max-ziplist-entries 512
hash-max-ziplist-value 64
list-max-ziplist-size -2
list-compress-depth 0
set-max-intset-entries 512
zset-max-ziplist-entries 128
zset-max-ziplist-value 64
hll-sparse-max-bytes 3000
stream-node-max-bytes 4096
stream-node-max-entries 100
activerehashing yes
client-output-buffer-limit normal 0 0 0
client-output-buffer-limit replica 256mb 64mb 60
client-output-buffer-limit pubsub 32mb 8mb 60
hz 10
dynamic-hz yes
aof-rewrite-incremental-fsync yes
rdb-save-incremental-fsync yes

4.创建文件夹,编写配置文件

 

cd ~
mkdir master6379 slave6380 slave6381

主master 6379

vim redis_6379.conf
daemonize yes
bind 0.0.0.0
port 6379
logfile redis6379.log
dbfilename dump.rdb
dir /root/master6379

从slave 6380

vim redis_6380.conf

 

 
daemonize yes
pidfile redis.pid
bind 0.0.0.0
port 6380
logfile redis6380.log
dbfilename dump.rdb
dir /root/slave6380
slaveof 127.0.0.1 6379
slave-read-only yes

从 slave 6381

vim redis_6381.conf
daemonize yes
pidfile redis.pid
bind 0.0.0.0
port 6381
logfile redis6381.log
dbfilename dump.rdb
dir /root/slave6381
slaveof 127.0.0.1 6379
slave-read-only yes

 

5.启动一主二从

redis-server redis_6379.conf
redis-server redis_6380.conf
redis-server redis_6381.conf

# 查看redis进程
ps aux | grep redis 

 

 6.编写哨兵配置
创建文件夹
cd ~
mkdir sentinel1 sentinel2 sentinel3

主哨兵 26379

vim sentinel_26379.conf
port 26379
daemonize yes
dir /root/sentinel1
bind 0.0.0.0
logfile "sentinel_6379.log"
sentinel monitor mymaster 127.0.0.1 6379 2
sentinel down-after-milliseconds mymaster 30000
sentinel parallel-syncs mymaster 1
sentinel failover-timeout mymaster 180000

从哨兵26380

vim sentinel_26380.conf
port 26380
daemonize yes
dir /root/sentinel1
bind 0.0.0.0
logfile "sentinel_6380.log"
sentinel monitor mymaster 127.0.0.1 6380 2
sentinel down-after-milliseconds mymaster 30000
sentinel parallel-syncs mymaster 1
sentinel failover-timeout mymaster 180000

从哨兵26381

vim sentinel_26381.conf
port 26381
daemonize yes
dir /root/sentinel1
bind 0.0.0.0
logfile "sentinel_6381.log"
sentinel monitor mymaster 127.0.0.1 6381 2
sentinel down-after-milliseconds mymaster 30000
sentinel parallel-syncs mymaster 1
sentinel failover-timeout mymaster 180000

7.启动三个哨兵

redis-sentinel sentinel_26379.conf
redis-sentinel sentinel_26380.conf
redis-sentinel sentinel_26381.conf

# 查看redis-sentinel进程
ps aux | grep redis-sentinel

三、代码

import redis
from redis.sentinel import Sentinel

# 连接哨兵服务器(主机名也可以用域名)
sentinel = Sentinel([('172.25.111.89', 26379),
                     ('172.25.111.89', 26380),
                     ('172.25.111.89', 26381)],
                    socket_timeout=5)
# print(sentinel)
# # 获取主服务器地址
master = sentinel.discover_master('mymaster')
print(master)

# 获取从服务器地址
slave = sentinel.discover_slaves('mymaster')
print(slave)

# 读写分离
# 获取主服务器进行写入
master = sentinel.master_for('mymaster', socket_timeout=5)
w_ret = master.set('foo', 'bar')

slave = sentinel.slave_for('mymaster', socket_timeout=0.5)
r_ret = slave.get('foo')
print(r_ret)

 

 

 

 

 

 

 

 

posted on 2021-03-03 15:06  輪滑少年  阅读(174)  评论(0编辑  收藏  举报