摘要:什么是一个分布式解决方案,多个节点构成的集群上层应用可以像使用单机的一样使用,底层会处理请求的转发,不停机的数据迁移等工作实例的计算能力汇集到一起,从而完成关于大数据和高并发量的的读写操作组成部分,处理客户端请求,支持协议,因此客户端访问
什么是Codis
一个分布式 Redis 解决方案,多个 Redis 节点构成的集群
上层应用可以像使用单机的 Redis 一样使用,Codis 底层会处理请求的转发,不停机的数据迁移等工作
Redis 实例的CPU计算能力汇集到一起,从而完成关于大数据和高并发量的的读写操作
组成部分Codis Proxy (codis-proxy),处理客户端请求,支持Redis协议,因此客户端访问Codis Proxy跟访问原生Redis没有什么区别;
Codis Dashboard (codis-config),Codis 的管理工具,支持添加/删除 Redis 节点、添加/删除 Proxy 节点,发起数据迁移等操作。codis-config 本身还自带了一个 http server,会启动一个 dashboard,用户可以直接在浏览器上观察 Codis 集群的运行状态;
Codis Redis (codis-server),Codis 项目维护的一个 Redis 分支,基于 2.8.21 开发,加入了 slot 的支持和原子的数据迁移指令;
ZooKeeper/Etcd,Codis 依赖 ZooKeeper 来存放数据路由表和 codis-proxy 节点的元信息,codis-config 发起的命令都会通过 ZooKeeper 同步到各个存活的 codis-proxy;
codis-ha,通过codis开放的api实现自动切换主从的工具。该工具会在检测到master挂掉的时候将其下线并选择其中一个slave提升为master继续提供服务
Codis架构生产环境部署:
1024个slot,落到64个group,每台服务器包含8个group
一个codis集群 = 8台物理机 = 8台物理机 (每台:8个group)= 64个group (每个group:16个slot) = 1024个slot
一台物理机运行16个Redis实例,2个Redis一个Group,一台master,一台slave
主从模式一个Master可以有多个Slaves,主流是一主二仆
默认配置下,master节点可以进行读和写,slave节点只能进行读操作,写操作被禁止
不要修改配置让slave节点支持写操作,没有意义,原因一,写入的数据不会被同步到其他节点;原因二,当master节点修改同一条数据后,slave节点的数据会被覆盖掉
slave节点挂了不影响其他slave节点的读和master节点的读和写,重新启动后会将数据从master节点同步过来
master节点挂了以后,不影响slave节点的读,Redis将不再提供写服务,master节点启动后Redis将重新对外提供写服务。
master节点挂了以后,不会slave节点重新选一个master(缺点)
哨兵模式sentinel模式是建立在主从模式的基础上,如果只有一个Redis节点,sentinel就没有任何意义
当master节点挂了以后,sentinel会在slave中选择一个做为master,并修改它们的配置文件,其他slave的配置文件也会被修改,比如slaveof属性会指向新的master
当master节点重新启动后,它将不再是master而是做为slave接收新的master节点的同步数据
sentinel因为也是一个进程有挂掉的可能,所以sentinel也会启动多个形成一个sentinel集群
当主从模式配置密码时,sentinel也会同步将配置信息修改到配置文件中,不许要担心
一个sentinel或sentinel集群可以管理多个主从Redis
sentinel最好不要和Redis部署在同一台机器,不然Redis的服务器挂了以后,sentinel也挂了
sentinel监控的Redis集群都会定义一个master名字,这个名字代表Redis集群的master Redis
缺点:
主从服务器的数据要经常进行主从复制,这样造成性能下降
当主服务器宕机后,从服务器切换成主服务器的那段时间,服务是不能用的
分片模式Codis会把所有的key分成1024个槽,这1024个槽对应着的就是Redis的集群,这个在Codis中是会在内存中维护着这1024个槽与Redis实例的映射关系。这个槽是可以配置,可以设置成 2048 或者是4096个
key的分配算法,先是把key进行CRC32 后,得到一个32位的数字,然后再hash%1024后得到一个余数,这个值就是这个key对应着的槽,这槽后面对应着的就是redis的实例
//Codis中Key的算法 hash = crc32(command.key) slot_index = hash % 1024 redis = slots[slot_index].redis redis.do(command)动态扩容
扩容Redis实例步骤:新增Redis配置 => 启动新的Redis => 新建Group,将reids添加进来 => 数据迁移
数据迁移步骤:
1、服务slot_1的group原为group 1,codis-config 现发起迁移指令 pre_migrate slot_1 to group 2,将slot_1状态标记为”pre_migrate”;
2、等待所有的proxy回复收到迁移指令;
3、将slot_1状态标记为”migrating”,服务slot_1的server group改为group2
4、codis-config不断发送SLOTSMGRT命令给group1的redis ,直到slot_1所有的key迁移完成;
5、迁移过程中, 如果请求 slot_1 的 key 数据, proxy 会将请求转发到group2上, proxy会先在group1上强行执行一次 MIGRATE key 将这个键值提前迁移过来. 然后再到group2上正常读取
6、将slot_1状态标记为”online”
slot_index = crc32(command.key) % 1024 if slot_index in migrating_slots: do_migrate_key(command.key) # 强制执行迁移 redis = slots[slot_index].new_redis else: redis = slots[slot_index].redis redis.do(command)
自动均衡策略:Codis 会在机器空闲的时候,观察Redis中的实例对应着的slot数,如果不平衡的话就会自动进行迁移
Redis - Pipelinepipeline通过减少客户端与redis的通信次数来实现降低往返延时时间,而且Pipeline 实现的原理是队列,而队列的原理是时先进先出,这样就保证数据的顺序性
原生批量命令(例如mget,mset等)是原子性,Pipeline是非原子性的
原生批量命令是一个命令对应多个key,Pipeline支持多个命令
原生批量命令是Redis服务端支持实现的,而Pipeline需要服务端与客户端的共同实现
技术延伸:一致性Hash与Redis集群文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/77785.html
阅读 2296·2021-11-24 10:33
阅读 1313·2019-08-30 15:43
阅读 3229·2019-08-29 17:24
阅读 3463·2019-08-29 14:21
阅读 2203·2019-08-29 13:59
阅读 1698·2019-08-29 11:12
阅读 2792·2019-08-28 18:00
阅读 1812·2019-08-26 12:17