共计 3228 个字符,预计需要花费 9 分钟才能阅读完成。
理解并从头搭建 Redis 集群
部分开发人员工作当中只是在应用中使用 redis,比如用来做数据结果的缓存。而且现在有很多不错的 redis 客户端工具(redisson),基本上可以不用关注 redis 命令就可以完成相当部分的功能。所以可能会对如下这些问题关注点不够:
- 如何容灾?即某个 redis 节点出了问题如何保证服务的高可用性
- 如何横向扩容?当数据量特别大时,如何解决单个 redis 的性能问题
- 集群至少需要几台机器?或者几个 redis 节点
- 集群搭建都利用什么技术,哪些工具?
如何容灾?
redis 提供了主从热备机制,主服务器的数据同步到从服务器,通过哨兵实时监控主服务器状态并负责选举主服务器。当发现主服务器异常时根据一定的算法重新选举主服务器并将问题服务器从可用列表中去除,最后通知客户端。主从是一对多的树型结构,如下图:
哨兵
哨兵是 sentinel 的中文名称,是 redis 出的一个高可用架构的工具,自身是一个独立的进程,可以同时监控一个以上的 redis 集群。
哨兵集群
基于高可用的考虑,哨兵自身也是需要支持集群的,如果只有一个哨兵就会存在单点问题。
哨兵决策
哨兵有一个数量配置,当多少个哨兵同时认为某个主服务不可用时才进行主从切换,比如总共有 5 个哨兵,当 3 个哨兵认为服务不可用时才决定做主从切换。这么做可以避免一些误切换,降低切换成本,比如瞬时的网络异常等。
如何横向扩容?
无论是 redis 还是其它一些数据库之类的产品,当单节点的数据容量达到一定上限后,服务对外提供的能力会越来越弱。redis 在高版本中提供了 redis-trib.rb 来实现集群功能,也可以使用第三方的工具 twemproxy。
去中心化,每个节点都是平等的
redis 集群从设计上没有考虑中心化,这样可以避免中心节点的单点等问题。每个节点都能掌握整个集群的状态,连接任意的节点都可以访问到所有的 key,就像单节点的 redis 一样。
集群原理图
自己理解画的,如有理解不对的地方可以指出。
key 与 redis 节点的关系
引入了 hasy solt,中文理解为哈希槽。总共 16384 个,我们操作的 key 通过取模算法确认 key 落在哪个槽上。
HASH_SLOT = CRC16(key) mod 16384
哈希槽与节点之间有一定关系,所以我们就可以将 key 分配到某个具体的 redis 节点上了。
详细的关系可再研究,简单的比如节点 A 负责 0 -5000 编号的哈希槽,节点 B 负责 5001-1000
一步一步搭建
开始搭建三主三从的集群,系统是 Ubuntu,采用 redis 提供的集群工具 redis-trib.rb。
- 安装最新 redis
- 创建 redis_cluster 目录,并且创建 7000 到 7005 这 6 个目录
- 将 redis 目录下的 redis.conf 复制到上面创建的 6 个目录中
- 分别修改 redis.conf 文件, 对 6 个文件做类似的修改。
port 7000 // 端口 7000
bind 127.0.0.1 // 默认 ip 为 127.0.0.1 需要改为其他节点机器可访问的 ip
daemonize yes // 后台运行
pidfile /var/run/redis_7000.pid //pidfile 文件对应 7000
cluster-enabled yes // 开启集群
cluster-config-file nodes_7000.conf // 集群的配置
cluster-node-timeout 15000 // 请求超时 默认 15 秒,可自行设置
bind 需要注意的就是需要配置为其它机器可以访问的 ip,否则无论是创建集群还是客户端连接都会有问题。
- 启动 6 个 redis
redis-server redis_cluster/7000/redis.conf
redis-server redis_cluster/7001/redis.conf
redis-server redis_cluster/7002/redis.conf
redis-server redis_cluster/7003/redis.conf
redis-server redis_cluster/7004/redis.conf
redis-server redis_cluster/7005/redis.conf
- 创建集群
redis 的 src 目录下有个 redis-trib.rb,将它复制到 /usr/local/bin 中,然后执行如下脚本:
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
–replicas 后面的 1 代表从服务器的个数,上面可以理解为前面 3 个为主服务器,后面三个分别做为从服务器,即三对主从。
执行过程中会遇到提示需要安装 ruby,安装完成之后又会提示安装 gem redis。
安装 gem redis,折腾了好久,最终发现是因为在国内访问不了某些网站导致通过 apt-get install 安装不成功,最后通过下载源码的方式安装成功。
再次执行创建集群的脚本, 出现如下提示:
输入 yes,继续
- 测试集群
连接客户端,由于我的所有节点都是在本地,所以不需要输入 ip,但需要加 - c 的参数。
redis-cli -c -p 7000
连接成功后,增加一个 key
set mykey 123
有一行提示语,指向到端口 7002,这说明虽然我们连接的是 7000 的实例,但通过 hash 算法最终会将 key 分配到 7002 的实例上。
再连接 7005 端口查询下 key,测试下是否任意一个实例都可以查询到 key
get mykey
显示指向到端口 7002
总结
真实环境的部署与单机部署还是差异比较大的,但也不复杂,尽管部分开发人员可能一辈子都不会有机会在线上搭建 redis 集群,但了解 redis 的高可用可扩展的方案对设计大型系统还是有比较大的帮助的,也有助于分析解决线上问题。看了上面的这些,对于本文开头提到的问题就不难理解了。
下面关于 Redis 的文章您也可能喜欢,不妨参考下:
Ubuntu 14.04 下 Redis 安装及简单测试 http://www.linuxidc.com/Linux/2014-05/101544.htm
Redis 主从复制基本配置 http://www.linuxidc.com/Linux/2015-03/115610.htm
Redis 集群明细文档 http://www.linuxidc.com/Linux/2013-09/90118.htm
Ubuntu 14.04 安装 Redis 与简单配置 http://www.linuxidc.com/Linux/2017-01/139075.htm
Ubuntu 16.04 环境中安装 PHP7.0 Redis 扩展 http://www.linuxidc.com/Linux/2016-09/135631.htm
CentOS 7.0 安装 Redis 3.2.1 详细过程和使用常见问题 http://www.linuxidc.com/Linux/2016-09/135071.htm
Ubuntu 16.04 环境中安装 PHP7.0 Redis 扩展 http://www.linuxidc.com/Linux/2016-09/135631.htm
Ubuntu 15.10 下 Redis 集群部署文档 http://www.linuxidc.com/Linux/2016-06/132340.htm
Redis 实战 中文 PDF http://www.linuxidc.com/Linux/2016-04/129932.htm
CentOS 7 下 Redis 的安装与配置 http://www.linuxidc.com/Linux/2017-02/140363.htm
Redis 的详细介绍:请点这里
Redis 的下载地址:请点这里
本文永久更新链接地址:http://www.linuxidc.com/Linux/2017-02/140637.htm