目录

Life in Flow

知不知,尚矣;不知知,病矣。
不知不知,殆矣。

X

Redis读写分离

读写分离的应用场景

读写分离架构
 海量并发性能瓶颈处理,横向扩展,大幅度提升抗压能力。
Redis 的主从数据是异步同步的,所以分布式的 Redis 系统并不满足「一致性」要求。当客户端在 Redis 的主节点修改了数据后,立即返回,即使在主从网络断开的情况下,主节点依旧可以正常对外提供修改服务,所以 Redis 满足「可用性」。
 运行一些额外的服务器,让它们与主服务器进行连接,然后将主服务器发送的数据副本并通过网络 进行准实时的更新(具体的更新速度取决于网络带宽)通过将读请求分散到不同的服务器上面进行处理, 用户可以从新添加的从服务器上获得额外的读查询处理能力。
Redis 已经发现了这个读写分离场景特别普遍,自身集成了读写分离供用户使用。我们只需在 Redis 的配置文件里面加上一条,【slaveof host port】语句
目前我们讲的 Redis 还只是主从方案,最终一致性,无故障转移功能,主 Master 节点宕机,则无法写入。

读写分离架构配置流程

# 创建目录
[root@localhost redis-replication]# mkdir /usr/local/redis-replication

# 新建两个目录
[root@localhost redis-replication]# cd /usr/local/redis-replication/
[root@localhost redis-replication]# mkdir 6379 6380

# 复制配置文件
[root@localhost redis-replication]# cp /test/redis-4.0.6/redis.conf  /usr/local/redis-replication/6379/
[root@localhost redis-replication]# cp /test/redis-4.0.6/redis.conf  /usr/local/redis-replication/6380/

# 修改配置文件 6379
[root@localhost 6379]# vim /usr/local/redis-replication/6379/redis.conf
bind  0.0.0.0 
port 6379 
logfile "6379.log" 
dbfilename "dump-6379.rdb" 
daemonize yes 
rdbcompression yes
[root@localhost 6379]# /test/redis-4.0.6/src/redis-server /usr/local/redis-replication/6379/redis.conf


# 修改配置文件 6380
[root@localhost 6379]# vim /usr/local/redis-replication/6380/redis.conf 
bind 0.0.0.0  
port 6380 
logfile "6380.log" 
dbfilename "dump-6380.rdb" 
daemonize  yes  
rdbcompression  yes  
slaveof 192.168.31.220 6379

[root@localhost 6379]# /test/redis-4.0.6/src/redis-server /usr/local/redis-replication/6380/redis.conf

# 查看进程
[root@localhost 6379]# ps -ef| grep redis
root      54093      1  0 10:56 ?        00:00:00 /test/redis-4.0.6/src/redis-server 0.0.0.0:6379
root      55430      1  0 11:01 ?        00:00:00 /test/redis-4.0.6/src/redis-server 0.0.0.0:6380
root      55448  26233  0 11:01 pts/1    00:00:00 grep --color=auto redis

# 登陆6379
[root@localhost 6379]# /test/redis-4.0.6/src/redis-cli -p 6379
127.0.0.1:6379> set name soulboy
OK

# 登陆6380
[root@localhost ~]# /test/redis-4.0.6/src/redis-cli -p 6380
127.0.0.1:6380> get name
"soulboy"

读写分离之数据同步原理

 进行复制中的主从服务器双方的数据库将保存相同的数据,概念上将这种现象称作“数据库状态一致”。

* RDB  全量持久化   
* AOF append only if  增量持久化

redis2.8 版本之前使用旧版复制功能 SYNC
 SYNC 是一个非常耗费资源的操作

  • 主服务器需要执行 BGSAVE 命令来生成 RDB 文件,这个生成操作会耗费主服务器大量的的 CPU、内存和磁盘读写资源
  • 主服务器将 RDB 文件发送给从服务器,这个发送操作会耗费主从服务器大量的网络带宽和流量,并对主服务器响应命令
  • 请求的时间产生影响:接收到 RDB 文件的从服务器在载入文件的过程是阻塞的,无法处理命令请求

2.8 版本之后使用 PSYNC

 PSYNC 命令具有完整重同步(full resynchronization)和部分重同步(partial resynchronization1)两种模式。部分重同步功能由以下三个部分构成:

读写分离重同步实现细节

 实现细节如下:

  • 主服务的复制偏移量(replication offset)和从服务器的复制偏移量
  • 主服务器的复制积压缓冲区(replication backlog),默认大小为 1M
  • 服务器的运行 ID(run ID),用于存储服务器标识,如从服务器断线重新连接,取到主服务器的运行 ID 与重接后的主服务器运行 ID 进行对比,从而判断是执行部分重同步还是执行完整重同步。

分布式系统高可用

 高可用 HA(High Availability)是分布式系统架构设计中必须考虑的因素之一,它通常是指,通过设计减少系统不能提供服务的时间。单点是系统高可用的大敌,应该尽量在系统设计的过程中避免单点。

  • 保证系统高可用,架构设计的核心准则是:冗余。
  • 每次出现故障需要人工介入恢复势必会增加系统的不可服务实践,实现自动故障转移
  • 重启服务,看服务是否每次都获取锁失败

分布式高可用经典架构环节分析

  • 【客户端层】到【反向代理层】的高可用,是通过反向代理层的冗余来实现的。以 nginx 为例:有两台 nginx,一台对线上提供服务,另一台冗余以保证高可用, 常见的实践是 keepalived 存活探测
  • 【反向代理层】到【Web 应用】的高可用,是通过站点层的冗余来实现的。假设反向代理层是 nginx,nginx.conf 里能够配置多个 Web 后端,并且 nginx 能够探测到多个后端的存活性。自动故障转移:当 web-server 挂了的时候,nginx 能够探测到,会自动的进行故障转移,将流量自动迁移到其他的 web-server,整个过程由 nginx 自动完成,对调用方是透明的。
  • 【服务层】到【缓存层】的高可用,是通过缓存数据的冗余来实现的。 Redis 天然支持主从同步,Redis 官方也有 sentinel 哨兵机制,来做 Redis 的存活性检测。
  • 【服务层】到【数据库层】的高可用,数据库层用“主从同步,读写分离”架构,所以数据库层的高可用,又分为“读库高可用”与“写库高可用”两类。读库采用冗余的方式实现高可用,写库采用 keepalived 存活探测 binlog 进行同步。

作者:Soulboy