本文共 6584 字,大约阅读时间需要 21 分钟。
redis要利用主从机制来做集群,势必会面临另外的局面。就是读写分离的问题,因此要么客户端知道主是哪个节点,从是哪些节点;要么是中间加代理,来实现主从复制的读写分离, 事实上构建起来还是比较不容易的
**所以就出现了一些其他的解决方案来实现的redis可用性的提升,扩展机制 有哪些,以及各自是如何实现的 ** 第一个叫做Twemproxy(由twitter研发)代理分片机制,意味着大家都不约而同地放弃主从,或者是主从仅仅是作为在分片之上的另外一种补充机制对redis而言做了主从,分离很麻烦,几乎也没有什么解决方案来分离,要以要么自己去研发一个所谓的分离工具,要么是放弃主从复制, 事实上互联网上开源的redis解决方案中都没有之间支撑使用简单的读写分离机制,而且还扩展了redis的写扩展逻辑。 可以基于分片的逻辑来使用redis,称为横向扩展, 这个横向扩展且不说redis cluster自己能实现,而是有一些解决方案,就是尝试着实现,对redis的读写操作,给直接分发到多个节点来实现,每一个节点只负责存储一部分数据, 读的时候也从这个节点读一部分数据,一样的逻辑,跟之前所讲,这种逻辑比较的固定的位置在于,很有可能他们是基于简单节点模型来完成分发的,所谓三个节点, 因此当一个键来存储或读取的时候,对节点取模,映射到哪个节点,这个键就在哪个节点上,所以这样一来,样本足够大的话,各节点只承担了三分之一左右的数据,读写都是三比一,但是一台机器宕了,此前取模的三分之一结果就没有了,重新取模的话,原来两个节点上的数据也找不到了 所以不能重新取模,所以只能固定对三取模
**所以可以对每一个节点做节点级的冗余,做主从,因此我们可以使用6个节点构建出三个主从同步集群来,每一个节点都是一主一从的,读写的时候都到主节点,从节点都是备用的,一旦主节点宕机了,把一个从节点提升为主节点即可 sentinel提供 构建一个三个节点的sentinel集群监控这三个主从复制集群 第一个叫 mymaster1 第二个叫 mymaster2 第三个 mymaster3 类似这种方式,任何一个节点,主的宕了,就把从的提升为主的,这样就工作起来了 ** **twemproxy就是基于这种逻辑工作的,所以是一种代理分片机制,twemproxy自己就是分发的这个节点,代理分发节点,所有用户请求收到以后,由它来分发至合理的redis节点,并取得数据以后响应给客户端,同时可以借助于sentinel,对它们做主从以后,完成所谓节点冗余 ** **但是对twemproxy而言 它的缺点: 单点故障(调度器是单点) 需依赖第三方软件,如keepalived(避免成为单点,只好做高可用,使用keepalived做高可用,因为它本地不需要存任何状态,因为把每个节点做hash计算以后,对固定数取模,得出的结果就可以映射了,是直接实时计算得到的,基于keepalived,简单的流动向ip并且备用的节点上启动twemproxy) 无法平滑地横向扩展(一加其他节点就需要重新取模了,所有的此前数据,都需要重新计算,手动的挪过去) 没有后台界面 代理分片机制引入更多的来回次数并增大延迟(用户的请求先到第一个节点这,它再构建新请求到服务器上,一个请求变成了两个,一次请求变成两次) 单核模式,无法充分利用多核,除非多实例(twemproxy自身也是单核的) twitter官方内部不再继续使用twemproxy(两三年前这是一个很不错解决方案), 目前国内都是下面的这种了 ** **豌豆荚 代理分片机制类似twemproxy,但是是基于go以及c语言开发的,twemproxy应该是java语言研发的,14年11月开源,非常稳定, 优点: 非常稳定,企业级解决方案 数据自动平衡 高性能 简单的测试显示较twemproxy快一倍 善用多核cpu 简单 ( 没有paxos类的协调机制(代理节点自身也可以多个节点,因为要依赖于zk来实现服务注册和发现,如果某个节点要使用codis要先向zk发请求,查询哪个节点可用,然后去连接那个节点,事实上代理节点都是分布式的,不要说你代理的redis的节点了) 没有主从复制(因为可用平滑扩展,是在数据块级别冗余的,不像twemproxy,是在节点级,codis是块级别进行冗余的,所以每个节点本身不需要再有从节点,宕了没事,其他节点还有副本,缺点也是代理分片)) 有后台界面 缺点 代理分片机制引入更多的来回次数并增大延迟 需要第三方软件支持协调机制 目前支持zookeeper及etcd 不支持主从复制,需要另外实现 codis采用了proxy的方案,所以必然会带来单机性能的损失(一次请求变为两次了,codis在国内,中小站点上还是比较流行的) 经测试,在不开pipeline的情况下,大概会损失40%左右的性能,在go环境下测试,学有余力建议测试,网上文档很多 作者就是tidb公司的创世人之一, **第三个解决方案redis cluster
**无中心节点,使用slot机制来定义的,使用16385个slot,编号从0-16384,假如你有5个节点,就把16385个slot平均分布到这些节点上,如果你有三个节点,就把这几个节点平均分布到3个节点上,有10个节点也是这个逻辑 优点: 无中心的P2PGossip分散式模式(无中心节点,而且是流言协议完成分布,所以客户端通讯连接任何一个节点都可以,要求每个客户端适配redis客户端,需要是智能客户端,知道这个节点宕了,还有其他哪些节点能用,不像codis,节点宕了,zk能告诉客户端换一个节点能用(要求你的客户端知道zk在什么地方,要配置客户端适用zk总线完成服务注册和服务发现)) 无中心所以没有单点 更少的来回次数并降低延迟 自动于多个redis节点进行分片(只要定义好了,就基于这些所谓的分片机制,和数量,做hash计算实现数据分布的,所以也不需要第三方软件来协调,但需要智能客户端) 不需要第三方软件支持协调机制 缺点: 依赖于redis3.0或 更高版本 需要时间验证其稳定性 没有后台界面 需要智能客户端 redis客户端必须支持redis cluster架构 较codis有更多的维护升级成本(每个节点升级都需要做滚动升级,升级比较麻烦) ** 但是这总是有个麻烦,依赖智能客户端,不能简单地像使用单个redis服务节点一样来使用,所以双方协调起来不是那么便捷,加一个中间层 国内有个著名电视台。马桶台(芒果TV),研发了cerberus cerberus就是给智能客户端与redis集群中间加了个中间层,使得客户端就像使用单机redis一样来使用redis cluster,所以可以理解为是redis集群的代理服务器,叫做cerberus 优点: 数据自动平衡 本身实现了redis的smar client (把后端redis集群的缺陷隐藏了,所以客户端就不需要smart client了 (此前讲了redis节点宕了,要么节点级冗余还是分片级冗余,slot是16385个是平均分布到这些节点上去的,哪些slot在哪些节点上是人工决定的,手动创建的 还需要冗余,在slot级很难冗余,每个节点都有从服务器,一旦节点宕机了,就把从提升为主,所以还要依赖于sentinel,帮你完成类似的工作)) (有了cerberus就不要sentinel了,自己就知道谁是主谁是从) 支持读写分离 缺点 依赖redis3.0或更高版本 代理分片机制引入更多的来回次数并增大延迟 需要时间验证其稳定性 没有后台界面 手动测试建议测试codis和redis cluster(官方的)http://blog.frognew.com/2017/03/redis-3.2-cluster-install-and-test.html
模拟了多个redis主机 每个节点都需要做冗余,每个节点都需要做从节点,为了不依赖太多物理服务器,这个文档实现了每一个物理主机,运行两个redis实例,一个监听在6379.一个监听在6380 虽然看起来精巧。但是物理节点宕机了就没有 了,仅测试可以使用,为了优化redis使用,尽量避免redis过于占用内存而导致使用交换分区 修改 vi /etc/sysctl.conf vm.overcommit_memory = 1 sysctl -p 为了方便redis使用,避免redis占用内存而导致使用交换分区 每一个配置节点,配置这几个参数,cluster端参数启动起来 找到cluster配置段 cluster-enabled yes 是否启用redis的集群功能(注释掉表示没启用,) cluster-config-file nodes-6379.conf(集群运行时,需要一个空配置文件,这个配置文件不需要配置任何内容,但redis进程会自己去写这个文件,所以要指定这个文件时什么) cluster-node-timeout 15000 (如果一个节点在这么长时间里联系不到,就认为是一个故障节点,判定一个节点是否故障超时的时长) 主节点宕了有个从节点,使用默认值基本可以解决问题 cluster-slave-validity-factor 10 cluster-migration-barrier 1 cluster-require-full-coverage yes主要配置cluster-enabled yes cluster-config-file nodes-6379.conf rpm安装就在etc目录下(编译安装指定的应该在的路径参数所定义),可以使用绝对路径,这样配置,redis集群就可以启动起来了。启动很容易但是,启动之后能作为集群工作很麻烦
cluster-enabled 是否开启集群配置 cluster-config-file 集群节点集群信息配置文件,每个节点都有一个,由redis生成和更新,配置时避免名称冲突 cluster-node-timeout 集群节点互连超时的阈值,单位毫秒 cluster-slave-validity-factor 进行故障转移时,salve会 申请成为master。有时slave会和master失联很久导致数据较旧,这样的slave不应该成为master。这个配置用来判断slave是否和master失联时间过长。 所以为什么要配置6379主,6388从,每个节点都需要主从,否则主节点一宕机,主节点就失去了配置以后直接启动服务即可
**启动进程以后看各个进程是否ok。现在要配置集群了 连接到对应的节点上,使用这个命令,cluster meet 见两外两个节点 ** 见面完成以后就可以用cluster info,查看当前集群状态, 这样配置,很有可能出问题,所以配置cluster集群可能需要使用一个工具,基于ruby的集群管理工具 这个程序较redis-trib。rb,redis源码目录下有这个文件,把redis的源码解开以后,把这个程序文件拿出来即可、、 能帮你创建集群 ,检查集群, 查看集群状态 修复集群 重新shared 重新均衡 添加节点 删除节点等等 这个脚本要想运行起来,需要配置好ruby环境 查看节点信息之后,要手动分配slot 要使用redis-cli连接至某一个节点,而后使用cluster addslot $i $1是传递给脚本的参数, $2 是起始数字 $3 是结束数字 所以在每一个节点上传递一个参数,$1就是节点的名称(地址),指明接下来要分配的slot数量,从几开始到几 创建完以后再次查看集群状态 **先添加从节点到集群中 ** 这些从节点要slaveof你的主节点 使用replication配置能否成为集群中从节点,这个信息是成为哪个主节点的从 我们现在只有三个节点,要测也只能按照这种方式测,每一个节点既是主又是从,分别6379和6380 把sentinel,redis都关闭了 】 每个主机上都有两个实例,编辑配置文件 把后面的删除,恢复到原来的配置文件 配置集群配置段 如果从节点超过多长时间,标记位不可以提升为主 或者先不加从节点,改一下效果,第二个主的也是一样的配置文件,所以可以复制过去 避免此前存在的数据影响集群,可以把数据也删除,其他节点也需要 现在为了简化不做从节点,做的话也比较简单,做一个配置文件,端口和文件修改,改完以后直接手动启动,不要systemctl,用redis.service -c 读配置文件即可 启动redis 现在服务业启动,使用cluster info命令 cluster infocluster_state:fail #集群状态 (fail是因为没有设置集群内容)
cluster_slots_assigned:0 #分配的slot数 cluster_slots_ok:0 #正确的slot数 cluster_slots_pfail:0 cluster_slots_fail:0 cluster_known_nodes:3 #当前的节点数 cluster_size:0 cluster_current_epoch:2 cluster_my_epoch:0 cluster_stats_messages_sent:171 cluster_stats_messages_received:171接下来需要为三个节点分配slot一共是16385,16385/3平均分成3份,然后每一个节点大概占多少 5461
使用cluster,添加addslot命令,$i,每一个都需要单独添加,连接到本机上,添加了5461 第二个节点就从5462添加到10922 第三个节点就从10923到16384 这个脚本无非就是让你添加多少个跟上面类似 都分配好了 CLUSTER INFO cluster_state:ok cluster_slots_assigned:16384 已经分配多少个 cluster_slots_ok:16384 cluster_slots_pfail:0 cluster_slots_fail:0 cluster_known_nodes:3 cluster_size:3 cluster_current_epoch:2 cluster_my_epoch:0 cluster_stats_messages_sent:3495 cluster_stats_messages_received:3495 现在就可以向集群存储数据了,因为集群状态已经正常 从节点可以不加,主节点本身就可以正常工作, 所以使用smart client就可以往这里写数据了 需要smart client cluster nodes 查看几个节点 **手动存数据试试,在节点2尝试一下,redis-cli连接到本机,使用set,设定key¥i 值是value¥i ** 、 现在本机上连接,会告诉你应该到哪个节点上去, 4998 在67上,redis-cli这个命令显然连接不到67,一位内不是smart-cli 能正确存到本机上的就存到本机上了,另外的节点就连不上去查看其他节点有没有数据,因为在节点2 上设置的,连接不进来,所以只有节点2 上才用成功的数据
以只有节点2 上才用成功的数据 所以没有smart-client的,没有办法测,链接任何节点都帮你连接到自己定向节点上 现在测试就差一环,smart client,这些都需要你用API写程序来实现,也没必要测试了,至少系统上成功了 注意:每个集群上的节点都需要一个从节点,万一节点一宕就麻烦了,而它也不需要sentinel,集群会自动把主节点宕机提升为主的,不需要自己额外用sentinel来配置 这个是cluster的优势,另外我们这里需要依赖于smart client,比较麻烦,最好可以试试这个程序,叫cerberus,学有余力的提供学, ,建议测试转载地址:http://ndkgn.baihongyu.com/