分析redis的各种使用情景
使用docker-compose演示redis的各种使用情景,最后介绍了codis
和kubernetes
方案
总结
模式 | 特点 |
---|---|
单机版-RDB | 备份快,但数据可能不完整 |
单机版-AOF | 备份慢,但是数据比较完整 |
1主N从 | 读写分离的典范 |
树状主从(N级缓存) | 为了规避主重启导致的大规模全量复制,但是需要维持每一个中间master的健康 |
主从自动切换(Sentinel) | 在主从的基础上加了Sentinel角色,通过Sentinel实现主从的自动切换 |
集群(N主N从) | 基于slot的key分片,客户端支持得不是很多,所以用的人不多 |
单机版
RDB模式(默认模式)
定期快照模式
version: '3' services: redis-master: image: redis ports: - "12660:6379" expose: - "6379" networks: - default entrypoint: - redis-server volumes: - ./data:/data
AOF模式
逐一写入,数据比较完整,文件较大,但恢复较慢
version: '3' services: redis-master: image: redis ports: - "12660:6379" expose: - "6379" networks: - default entrypoint: - redis-server - --appendonly yes volumes: - ./data:/data
主从复制版
1主N从
这种模式简单粗暴,但是master一旦重启,多从节点全量复制,IO将会比较繁重
version: '3' services: redis-master: image: redis ports: - "12660:6379" expose: - "6379" networks: - default entrypoint: - redis-server - --save 1 1 volumes: - ./data:/data redis-slave1: image: redis ports: - "12661:6379" expose: - "6379" networks: - default entrypoint: - redis-server - --slaveof redis-master 6379 - --slave-serve-stale-data yes #当从机与主机断开连接时,或者当复制仍在进行时,slave仍然会回复client请求, 尽管数据可能会出现过期或者如果这是第一次同步,数据集可能为空。 - --slave-read-only yes #0作为一个特殊的优先级,标识这个slave不能作为master - --slave-priority 100 redis-slave2: image: redis ports: - "12662:6379" expose: - "6379" entrypoint: - redis-server - --slaveof redis-master 6379 - --slave-serve-stale-data yes #当从机与主机断开连接时,或者当复制仍在进行时,slave仍然会回复client请求, 尽管数据可能会出现过期或者如果这是第一次同步,数据集可能为空。 - --slave-read-only yes #0作为一个特殊的优先级,标识这个slave不能作为master - --slave-priority 100
树状主从(N级缓存)
从节点作为主节点.
这种模式规避了单master
version: '3' services: redis-master: image: redis ports: - "12660:6379" expose: - "6379" networks: - default entrypoint: - redis-server - --save 1 1 volumes: - ./data:/data redis-slave1: image: redis ports: - "12661:6379" expose: - "6379" networks: - default entrypoint: - redis-server - --slaveof redis-master 6379 - --slave-serve-stale-data yes #当从机与主机断开连接时,或者当复制仍在进行时,slave仍然会回复client请求, 尽管数据可能会出现过期或者如果这是第一次同步,数据集可能为空。 - --slave-read-only yes #0作为一个特殊的优先级,标识这个slave不能作为master - --slave-priority 100 # - --masterauth xxx redis-slave2: image: redis ports: - "12662:6379" expose: - "6379" entrypoint: - redis-server - --slaveof redis-slave1 6379 - --slave-serve-stale-data yes #当从机与主机断开连接时,或者当复制仍在进行时,slave仍然会回复client请求, 尽管数据可能会出现过期或者如果这是第一次同步,数据集可能为空。 - --slave-read-only yes #0作为一个特殊的优先级,标识这个slave不能作为master - --slave-priority 100 # - --masterauth xxx
主从自动切换(Sentinel模式)
这时需要引入 Sentinel 的概念
Redis 的 Sentinel 系统用于管理多个 Redis 服务器(instance), 该系统执行以下三个任务:
- 监控(Monitoring): Sentinel 会不断地检查你的主服务器和从服务器是否运作正常。
- 提醒(Notification): 当被监控的某个 Redis 服务器出现问题时, Sentinel 可以通过 API 向管理员或者其他应用程序发送通知。
- 自动故障迁移(Automatic failover): 当一个主服务器不能正常工作时, Sentinel 会开始一次自动故障迁移操作, 它会将失效主服务器的其中一个从服务器升级为新的主服务器, 并让失效主服务器的其他从服务器改为复制新的主服务器; 当客户端试图连接失效的主服务器时, 集群也会向客户端返回新主服务器的地址, 使得集群可以使用新主服务器代替失效服务器。
默认的Sentinel配置去掉注释后长这样
port 26379 daemonize no pidfile /var/run/redis-sentinel.pid logfile "" dir /tmp # 监视主服务器,下线master需要2个Sentinel同意 sentinel monitor mymaster redis-master 6379 2 # 30秒内有效回复视为master健康,否则下线 sentinel down-after-milliseconds mymaster 30000 # 故障转移时,从服务器同部数最大值 sentinel parallel-syncs mymaster 1 # 1. 同一个sentinel对同一个master两次failover之间的间隔时间。 # 2. 当一个slave从一个错误的master那里同步数据开始计算时间。直到slave被纠正为向正确的master那里同步数据时。 # 3.当想要取消一个正在进行的failover所需要的时间。 # 4.当进行failover时,配置所有slaves指向新的master所需的最大时间。不过,即使过了这个超时,slaves依然会被正确配置为指向master,但是就不按parallel-syncs所配置的规则来了。 sentinel failover-timeout mymaster 90000
基本格式是sentinel <选项的名字> <主服务器的名字> <选项的值>
原本我想通过docker-compose up --scale redis-sentinel=3
直接启动3个容器,结果发现这容器竟然会修改配置文件,所以只能分开写了
初版
# docker-compose up --scale redis-sentinel=3 虽然可以启动,但是3个容器同时写同一个文件,感觉不是很好 version: '3' services: redis-master: image: redis ports: - "12660:6379" expose: - "6379" entrypoint: - redis-server - --save 1 1 volumes: - ./data:/data # 重启策略改为no手动让他宕机模拟主从切换 restart: "no" redis-slave1: image: redis ports: - "12661:6379" expose: - "6379" entrypoint: - redis-server - --slaveof redis-master 6379 - --slave-serve-stale-data yes #当从机与主机断开连接时,或者当复制仍在进行时,slave仍然会回复client请求, 尽管数据可能会出现过期或者如果这是第一次同步,数据集可能为空。 - --slave-read-only yes #0作为一个特殊的优先级,标识这个slave不能作为master - --slave-priority 100 # - --masterauth xxx redis-slave2: image: redis ports: - "12662:6379" expose: - "6379" entrypoint: - redis-server - --slaveof redis-slave1 6379 - --slave-serve-stale-data yes #当从机与主机断开连接时,或者当复制仍在进行时,slave仍然会回复client请求, 尽管数据可能会出现过期或者如果这是第一次同步,数据集可能为空。 - --slave-read-only yes #0作为一个特殊的优先级,标识这个slave不能作为master - --slave-priority 100 # - --masterauth xxx redis-sentinel: image: redis expose: - "26379" entrypoint: - redis-server - /usr/local/etc/redis/redis.conf - --sentinel volumes: - ./redis-sentinel.conf:/usr/local/etc/redis/redis.conf
最终版:
version: '3' services: redis-master: image: redis ports: - "12660:6379" expose: - "6379" entrypoint: - redis-server - --save 1 1 volumes: - ./data:/data # 重启策略改为no手动让他宕机模拟主从切换 restart: "no" redis-slave1: image: redis ports: - "12661:6379" expose: - "6379" entrypoint: - redis-server - --slaveof redis-master 6379 - --slave-serve-stale-data yes #当从机与主机断开连接时,或者当复制仍在进行时,slave仍然会回复client请求, 尽管数据可能会出现过期或者如果这是第一次同步,数据集可能为空。 - --slave-read-only yes #0作为一个特殊的优先级,标识这个slave不能作为master - --slave-priority 100 # - --masterauth xxx redis-slave2: image: redis ports: - "12662:6379" expose: - "6379" entrypoint: - redis-server - --slaveof redis-slave1 6379 - --slave-serve-stale-data yes #当从机与主机断开连接时,或者当复制仍在进行时,slave仍然会回复client请求, 尽管数据可能会出现过期或者如果这是第一次同步,数据集可能为空。 - --slave-read-only yes #0作为一个特殊的优先级,标识这个slave不能作为master - --slave-priority 100 # - --masterauth xxx redis-sentinel1: image: redis expose: - "26379" entrypoint: - redis-server - /usr/local/etc/redis/redis.conf - --sentinel volumes: - ./redis-sentinel1.conf:/usr/local/etc/redis/redis.conf redis-sentinel2: image: redis expose: - "26379" entrypoint: - redis-server - /usr/local/etc/redis/redis.conf - --sentinel volumes: - ./redis-sentinel2.conf:/usr/local/etc/redis/redis.conf redis-sentinel3: image: redis expose: - "26379" entrypoint: - redis-server - /usr/local/etc/redis/redis.conf - --sentinel volumes: - ./redis-sentinel3.conf:/usr/local/etc/redis/redis.conf
sentinel启动之后,配置发生了变化
这些内容没了
sentinel monitor mymaster redis-master 6379 2 sentinel down-after-milliseconds mymaster 30000 sentinel parallel-syncs mymaster 1
变成
sentinel myid 3ae98d6815c1a9b941f8283b7e48bfeef7435905 sentinel deny-scripts-reconfig yes # Generated by CONFIG REWRITE sentinel config-epoch mymaster 0 sentinel leader-epoch mymaster 0 sentinel known-replica mymaster 172.24.0.4 6379 sentinel known-sentinel mymaster 172.24.0.7 26379 19ac7e0519e3c30a75e23bac34a7033594256c54 sentinel known-sentinel mymaster 172.24.0.5 26379 c596734a7f55ba2b6c7e3e81562aa6687e45fdeb sentinel current-epoch 0
之后通过docker ps
和docker stop
手动停掉了master那个容器,sentinel发觉了,并重新选主.
此时通过redis-cli
输入info,发现它已经成功变成了可以写入数据的master
# Generated by CONFIG REWRITE sentinel config-epoch mymaster 1 sentinel leader-epoch mymaster 1 sentinel known-replica mymaster 172.24.0.3 6379 sentinel known-replica mymaster 172.24.0.2 6379 sentinel known-sentinel mymaster 172.24.0.7 26379 19ac7e0519e3c30a75e23bac34a7033594256c54 sentinel known-sentinel mymaster 172.24.0.5 26379 c596734a7f55ba2b6c7e3e81562aa6687e45fdeb sentinel current-epoch 1
此时重启master,虽然他以server形式启动,但是角色已经自动被贬为slave.
此时master没有变化,所以sentinel的配置内容没有变
集群版(N主N从)
集群基于16384个slot做分片.目前各语言客户端实现比较少.所以用的人不是很多.
在docker中运行时,需要使用host网络模式(--net=host)
redis-trib.rb
redis版本<5时,可以用redis-trib.rb
建集群
./redis-trib.rb create --replicas 1 127.0.0.1:7000 127.0.0.1:7001 \ 127.0.0.1:7002 127.0.0.1:7003 127.0.0.1:7004 127.0.0.1:7005 # 引入新节点 ./redis-trib.rb add-node 127.0.0.1:7006 <任意节点IP>:<节点端口> # 重新分片 ./redis-trib.rb reshard <任意节点IP>:<节点端口>
redis-cli
=5直接用redis-cli即可.
redis-cli --cluster create 127.0.0.1:7000 127.0.0.1:7001 \ 127.0.0.1:7002 127.0.0.1:7003 127.0.0.1:7004 127.0.0.1:7005 \ --cluster-replicas 1 redis-cli --cluster reshard 127.0.0.1:7000 redis-cli reshard <host>:<port> --cluster-from <node-id> --cluster-to <node-id> --cluster-slots <number of slots> --cluster-yes redis-cli --cluster add-node 127.0.0.1:7006 127.0.0.1:7000 # Adding a new node as a replica redis-cli --cluster add-node 127.0.0.1:7006 127.0.0.1:7000 --cluster-slave redis-cli --cluster add-node 127.0.0.1:7006 127.0.0.1:7000 --cluster-slave --cluster-master-id 3c3a0c74aae0b56170ccb03a76b60cfe7dc1912e redis-cli --cluster del-node 127.0.0.1:7000 `<node-id>`
集群指令
CLUSTER REPLICATE <master-node-id> cluster nodes
Kubernetes
个人觉得吧,redis跟Kubernetes不是特别契合.kubernetes本身有网络瓶颈的问题,通过svc去访问,频繁DNS解析也不好对吧.这对于高频访问redis的场景来说是致命的.
而且pod这种易失架构注定了在Kubernetes上面用redis要么用数据卷挂载,要么用主从自动切换模式(纯内存的话至少要1主2从,并且用反亲和度错开彼此的运行节点).
主从和单机版倒好解决,单机的话挂载好数据卷,主从的话,主和从分开2个deploy/statefulset部署即可.
但是集群版就比较麻烦.官方的设计还是偏向于传统二进制人工运维,没有做到云原生
看了一下官方的helm chart,也是用的主从模式.
codis
codis是redis集群没出来之前,豌豆荚团队做的一个方案,通过proxy,隔离了后端的redis集群
优点
- 支持Kubernetes
- 有web图形界面,方便运维
- Redis获得动态扩容/缩容的能力,增减redis实例对client完全透明、不需要重启服务
缺点
- 稳定性堪忧
- 依赖于国内的豌豆荚团队开发,迭代速度较慢
- 原版的docker镜像较大,没有根据组件进行分开
- 基于redis 3.x,而且很多原生的redis指令被阉割了
- 强依赖注册中心(Zookeeper、Etcd、Fs)
我们用了几个月吧,到后期频繁出现
ERR handle response, backend conn reset
此外,日常观察发现pod退出/重启困难.如果某个group节点全部挂掉的话,整个集群将不可读写.
综上,codis已经影响到了严重影响到了我们程序的正确性,决定弃用codis.改为普通的1主N从的模式.
参考链接
低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
visual studio中运行docker支持简记
很久以前学过一段时间的docker,那时装了电脑卡得受不了,学了一会就卸载了,最近电脑又装上了docker,感觉好像没有以前这么卡了,还是同一台电脑surface pro4, 试了一下visual studio中做的网站运行在docker上,下面是一些简记 环境:win10 + docker desktop + visual studio 2017 + mysql , 其中MYSQL是安装在c:/mysql 里的 打开visual studio 网站项目,在Niunan.Blog.Web项目上右键添加doker支持,选linux 支持, 会生成Dockerfile文件 直接点那个绿三角图标运行,结果等了好久好久,卡在那个界面上 原来是docker正在下载底层的包的,会很慢很慢,可以先停掉VS。然后在cmd命令行下运行 docker pull microsoft/dotnet:2.2-aspnetcore-runtime 和 docker pull microsoft/dotnet:2.2-sdk 然后再点绿三角图标运行,运行成功了,弹出浏览器了,不过显示不了 后来发现是我Program...
- 下一篇
阿里云建站有多种方式,本篇教程主要介绍自助建站的流程
使用阿里云建站有多种方式,本篇教程主要介绍自助建站的流程。 建站方式使用阿里云搭建网站有多种方式,您可参照下表选择合适的建站方式 步骤1. 选择服务器不同网站类型需要的ECS配置不同,请您确认网站规模与访问人数。一般情况下,小型网站只需要选择基础配置即可。购买实例的步骤请参见使用向导创建实例。 ECS主要计费方式为预付费(包年包月和按周付费)和按量付费,详细的计费规则请参见计费概述。您可以使用ECS价格计算器了解不同配置对应的价格。 步骤2. 部署网站您可参见自助建站方式汇总来选择网站的部署方式。 步骤3. 购买和备案域名购买域名。注册域名。输入想要的域名,未被占用即可注册,具体操作请参见注册通用域名。域名后缀通常为.com或.cn,更多后缀请参见域名区别。实名认证。流程请参见域名实名认证概述。备案域名。准备备案:因各省管局要求存在差异,所需资料也不相同,请根据各地区管局备案规则准备资料,或访问工信部备案管理系统(www.miitbeian.gov.cn)了解细则。详情请参见备案基础。若之前尚未进行过工信部备案,请参见首次备案完成首次备案接入。其它备案场景请参见备案入门引导。 步骤4....
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- SpringBoot2整合Redis,开启缓存,提高访问速度
- SpringBoot2配置默认Tomcat设置,开启更多高级功能
- Hadoop3单机部署,实现最简伪集群
- CentOS7,CentOS8安装Elasticsearch6.8.6
- CentOS6,7,8上安装Nginx,支持https2.0的开启
- Docker使用Oracle官方镜像安装(12C,18C,19C)
- SpringBoot2编写第一个Controller,响应你的http请求并返回结果
- CentOS7安装Docker,走上虚拟化容器引擎之路
- CentOS8编译安装MySQL8.0.19
- Docker安装Oracle12C,快速搭建Oracle学习环境