redis集群讨论

得意莫骄傲,失意莫沮丧。 得意莫骄傲,失意莫沮丧。     2022-08-04     519

关键词:

一、生产应用场景

二、存储架构演变

三、应用最佳实践

四、运维经验总结


第1、2节:介绍redis cluster在唯品会的生产应用场景,以及存储架构的演变。
第3节:redis cluster的稳定性,应用成熟度,踩到过那些坑,如何解决这些问题?这部分是大家比较关心的内容。
第4节:简单介绍大规模运营的一些经验,包括部署、监控、管理以及redis工具开发。

一、生产应用场景

1、业务范围

redis cluster在唯品会主要应用于后端业务,用作内存存储服务。主要大数据实时推荐/ETL、风控、营销三大业使用。cluster用于取代当前 twemproxy三层架构,作为通用的存储架构。redis cluster可以大幅度简化我们的存储架构,也解决twemproxy架构无法在线扩容节点的问题。目前我们在线有生产几十个cluster集群,约2 千个instances,单个集群最大达到250+instances。
这是我们的生产应用场景,主要是后端业务的存储,目前没有作为cache使用的场景。

2、大数据、风控、营销系统的特征

  • cluster作为数据量大, 单个cluster集群在几十个GB到上TB级别内存存储量。
  • 作为后端应用的存储,数据来源主要以下三种方式:

    • Kafka --> Redis Cluster,Storm/Spark实时
    • Hive --> Redis Cluster, MapReduce程序
    • MySQL --> Redis Cluster,Java/C++程序。
  • 数据由离线/实时job生成, 读写请求量大, 对读写性能也要求高。

  • 业务高峰期请求量急剧上升,几倍的读写量增加,需要多个redis实例承担业务的读写压力。
  • 业务需求变化快, schema变化频繁。如果使用MySQL作为存储,那么将会是频繁的DLL变更,而且需要做online schema change。
  • 大促销活动时扩容频繁。

3、为什么选择redis cluster

3.1 cluster适合我们后端生产应用场景
  • 在线水平扩展能力,能够解决我们大量的扩容需求。
  • Failover能力和高可用性。
  • 虽然cluster不保证主从数据强一致性,但是后端业务能够容忍failover后少量的数据丢失。
3.2 架构简单
  • 无中心架构,各个节点度等。slave节点提供数据冗余,master节点异常时提升为master。
  • 取代twemproxy三层架构,系统复杂性降低。
  • 可以节约大量的硬件资源,我们的Lvs + Twemproxy层 使用了近上千台物理机器。
  • 少了lvs和twemproxy层,读写性能提升明显。响应时间从100-200us减少到50-100us。
  • 系统瓶颈更少。lvs层网卡和pps吞吐量瓶颈;对于请求长度较大的业务,twemproxy单节点性能低。
    总结下,我们选择redis cluster主要这两点原因:简单、扩展性。另外,我们用cluster取代twemproxy集群,三层架构实在是很令人头疼,复杂、瓶颈多、管理不方面。

二、存储架构演变

1、架构演变

 

在2014年7月,为了准备当时的814撒娇节大促销活动,我们把单个redis的服务迁移到twemproxy上。twemproxy在后端快速完成数据分片和扩容。为了避免再次扩容,我们静态分配足够多的资源。
之后,twemproxy暴露出来的系统瓶颈很多,资源使用很多,也存在一定的浪费。我们决定用redis cluster取代这种复杂的三层架构。
redis cluster GA之后,我们就开始上线使用。最初是3.0.2 版本,后面大量使用3.0.3 ,上个月开始使用3.0.7版本。

下面简单对比下两种架构,解析下他们的优缺点。

2、Twemproxy架构

优点
  • sharding逻辑对开发透明,读写方式和单个redis一致。
  • 可以作为cache和storage的proxy(by auto-eject)。
缺点
  • 架构复杂,层次多。包括lvs、twemproxy、redis、sentinel和其控制层程序。
  • 管理成本和硬件成本很高。
  • 2 * 1Gbps 网卡的lvs机器,最大能支撑140万pps。
  • 流量高的系统,proxy节点数和redis个数接近。
  • Redis层仍然扩容能力差,预分配足够的redis存储节点。

 

这是twemproxy的架构,客户端直接连接最上面的lvs(LB),第二层是同构的twemproxy节点,下面的redis master节点以及热备的slave节点,另外还有独立的sentinel集群和切换控制程序,twemproxy先介绍到这里。

3、Redis Cluster架构

优点
  • 无中心 架构。
  • 数据按照slot存储分布在多个redis实例上。
  • 增加slave做standby数据副本,用于failover,使集群快速恢复。
  • 实现故障auto failover。节点之间通过gossip协议交换状态信息;投票机制完成slave到master角色的提升。
  • 亦可manual failover,为升级和迁移提供可操作方案。
  • 降低硬件成本和运维成本,提高系统的扩展性和可用性。
缺点
  • client实现复杂,驱动要求实现smart client,缓存slots mapping信息并及时更新。
  • 目前仅JedisCluster相对成熟,异常处理部分还不完善,比如常见的“max redirect exception”。
  • 客户端的不成熟,影响应用的稳定性,提高开发难度。
  • 节点会因为某些原因发生阻塞(阻塞时间大于clutser-node-timeout),被判断下线。这种failover是没有必要,sentinel也存在这种切换场景。
    cluster的架构如下:

cluster.jpg

图上只有master节点(slave略去),所有节点构成一个完全图,slave节点在集群中与master只有角色和功能的区别。

架构演变讲完了,开始讲第三部分,也是大家最感兴趣的一部分.

三、应用最佳实践

  • redis cluster的稳定性如何?
  • 存在哪些坑?
  • develop guideline & best practice

1、稳定性

  • 不扩容时集群非常稳定。
  • 扩容resharding时候,早期版本的Jedis端有时会出现“max-redirect”异常。
    分析Jedis源码,请求重试次数达到了上限,仍然没有请求成功。两方面分析:redis连接不上?还是集群节点信息不一致?
  • 存活检测机制缺陷
    redis 存活检测机制可能因为master 节点上慢查询、阻塞式命令、或者其它的性能问题导致长时间没有响应,这个节点会认为处于failed状态,并进行切换。这种切换是没必要的。
    优化策略:
    a) 默认的cluster-node-timeout为15s,可以适当增大;
    b) 避免使用会引起长时间阻塞的命令,比如save/flushdb等阻塞操作,或者keys pattern这种慢查询。

总体来说,redis cluster已经非常稳定了,但是要注意一些应用中的小问题,下面是5个坑,大家注意了.

2、有哪些坑?

2.1 迁移过程中Jedis“Max Redirect”异常。
  • github上讨论的结果是程序retry。
  • max redirt issues:https://github.com/xetorthio/jedis/issues/1238
  • retry时间应该大于failover 时间。
  • Jedis参数优化调整:增大jedis中的‘DEFAULT_MAX_REDIRECTIONS’参数,默认值是5.
  • 避免使用multi-keys操作,比如mset/mget. multi-key操作有些客户端没有支持实现。
2.2 长时间阻塞引起的不必要的failover
  • 阻塞的命令。比如save/flushall/flushdb
  • 慢查询。keys *、大key的操作、O(N)操作
  • rename危险操作:
    • rename-command FLUSHDB REDIS_FLUSHDB
    • rename-command FLUSHALL REDIS_FLUSHALL
    • rename-command KEYS REDIS_KEYS
2.3 同时支持ipv4和ipv6侦听服务埋下的坑

具体现象:redis启动正常,节点的协议端口只有ipv6 socket创建正常。异常节点也无法加入到集群中,也无法获取epoch。
解决方法:启动时指定网卡ipv4地址,也可以是0.0.0.0,配置文件中添加:bind 0.0.0.0
这个是在setup集群的时候发生过的一个问题,bind 0.0.0.0虽然存在一些安全性问题,但是是比较简单通用的解决方法。

2.4 数据迁移速度较慢
  • 主要使用的redis-trib.rb reshard来完成数据迁移。
  • redis-3.0.6版本以前migrate操作是单个key逐一操作。从redis-3.0.6开始,支持单次迁移多个key。
  • redis集群内部最多只允许一个slot处于迁移状态,不能并发的迁移slots。
  • redis-trib.rb reshard如果执行中断,用redis-trib.rb fix修复集群状态。
2.5 版本选择/升级建议
  • 我们已经开始使用3.0.7版本,很多3.2.0修复的bug已经backport到这个版本。
  • 另外我们也开始测试3.2.0版本,内存空间优化很大。
  • Tips
    • redis-trib.rb支持resharding/rebalance,分配权重。
    • redis-trib.rb支持从单个redis迁移数据到cluster集群中。

后面2点不算坑把,算是不足,tips也很实用.开始分享下最佳实践。

3、最佳实践

3.1 应用做好容错机制
  • 连接或者请求异常,进行连接retry和reconnect。
  • 重试时间应该大于cluster-node-time时间
    还是强调容错,这个不是针对cluster,所有的应用设计都适用。
3.2 制定开发规范
  • 慢查询,进程cpu 100%、客户端请求变慢,甚至超时。
  • 避免产生hot-key,导致节点成为系统的短板。
  • 避免产生big-key,导致网卡打爆、慢查询。
  • TTL, 设置合理的ttl,释放内存。避免大量key在同一时间段过期,虽然redis已经做了很多优化,仍然会导致请求变慢。
  • key命名规则。
  • 避免使用阻塞操作,不建议使用事务。
    开发规范,使你们的开发按照最优的方式使用nosql。
3.3 优化连接池使用
  • 主要避免server端维持大量的连接。
  • 合理的连接池大小。
  • 合理的心跳检测时间。
  • 快速释放使用完的连接。
  • Jedis一个连接创建异常问题(fixed):
    https://github.com/xetorthio/jedis/issues/1252

连接问题是redis开发使用中最常见的问题,connection timeout/read timeout,还有borrow connection的问题。

3.4 区分redis/twemproxy和cluster的使用
  • redis建议使用pipeline和multi-keys操作,减少RTT次数,提高请求效率。
  • twemproxy也支持pipeline, 支持部分的multi-key可以操作。
  • redis cluster不建议使用pipeline和multi-keys操作,减少max redirect产生的场景。

区分redis 和 cluster的使用,一方面是数据分片引起的;另一方面,与client的实现支持相关。

3.5 几个需要调整的参数

1)设置系统参数vm.overcommit_memory=1,可以避免bgsave/aofrewrite失败。
2)设置timeout值大于0,可以使redis主动释放空闲连接。
3)设置repl-backlog-size 64mb。默认值是1M,当写入量很大时,backlog溢出会导致增量复制不成功。
4)client buffer参数调整
client-output-buffer-limit normal 256mb 128mb 60
client-output-buffer-limit slave 512mb 256mb 180

四、运维经验总结

1、自动化管理

  • CMDB管理所有的资源信息。
  • Agent方式上报硬软件信息。
  • 标准化基础设置。机型、OS内核参数、软件版本。
  • Puppet管理和下发标准化的配置文件、公用的任务计划、软件包、运维工具。
  • 资源申请自助服务。
2、自动化监控
  • zabbix作为主要的监控数据收集工具。
  • 开发实时性能dashboard,对开发提供查询。
  • 单机部署多个redis,借助于zabbix discovery。
  • 开发DB响应时间监控工具Titan。
  • 基本思想来源于pt-query-degest,通过分析tcp应答报文产生日志。flume agent + kafka收集,spark实时计算,hbase作为存储。最终得到hotquery/slowquery,request source等性能数据。

3、自动化运维

  • 资源申请自助服务化。
  • 如果申请合理,一键即可完成cluster集群部署。
    能不动手的,就坚决不动手,另外,监控数据对开发开发很重要,让他们了解自己服务性能,有时候开发会更早发现集群的一些异常行为,比如数据不过期这种问题,运维就讲这么多了,后面是干货中的干货,由deep同学开发的几个实用工具。

4、redis开源工具介绍

4.1 redis实时数据迁移工具

1) 在线实时迁移
2) redis/twemproxy/cluster 异构集群之间相互迁移。
3)github:https://github.com/vipshop/redis-migrate-tool

4.2 redis cluster管理工具

1)批量更改集群参数
2)clusterrebalance
3)很多功能,具体看github :
https://github.com/deep011/redis-cluster-tool

4.3 多线程版本Twemproxy

1)大幅度提升单个proxy的吞吐量,线程数可配置。
2)压测情况下,20线程达到50w+qps,最优6线程达到29w。
3)完全兼容twemproxy。
4)github:
https://github.com/vipshop/twemproxies

4.4 在开发的中的多线redis

1)Github:
https://github.com/vipshop/vire

2)欢迎一起参与协作开发,这是我们在开发中的项目,希望大家能够提出好的意见。

问答(陈群和申政解答):

问题1:版本更新,对数据有没有影响?

答:我们重启升级从2.8.17到3.0.3/3.0.7没有任何的异常。3.0到3.2我们目前还没有实际升级操作过。

问题2:请问下sentinel模式下有什么好的读写分离的方法吗

答:我们没有读写分离的使用,读写都在maste;集群太多,管理复杂;此外,我们也做了分片,没有做读写分离的必要;且我们几乎是一主一从节点配置

问题3:redis的fork主要是为了rdb吧,去掉是为了什么呢

答:fork不友好

问题4:如果不用fork,是怎么保证rdb快照是精确的,有其他cow机制么

答:可以通过其他方法,这个还在探究阶段,但目标是不用fork

问题5:就是redis cluster模式下批量操作会有很多问题,可是不批量操作又会降低业务系统的性能

答:确实存在这方面的问题,这方面支持需要客户端的支持,但是jedis的作者也不大愿意支持pipeline或者一些multi key操作。如果是大批量的操作,可以用多线程提高客户端的吞吐量。
(Redis中国用户组版权所有,转载请注明来源)

附录:

嘉宾微信:qunchenmy
技术博客:[http://mdba.cn]
微博:[http://weibo.com/sylarqun]
Redis中国用户组官网:[http://redis.cn]
Redis中国用户组官方微博@redis2016
Redis知识图谱:
[http://lib.csdn.net/base/redis]
[http://lib.csdn.net/mobile/base/34]
群二维码:



文/Redis中国用户组(简书作者)
原文链接:http://www.jianshu.com/p/ee2aa7fe341b
著作权归作者所有,转载请联系作者获得授权,并标注“简书作者”。

redis的安装配置及简单集群部署

最近针对中铁一局项目,跟事业部讨论之后需要我们的KF平台能够接入一些开源的数据库,于是这两天研究了一下Redis的原理。1. Redis的数据存储原理及简述1.1Redis简述Redis是一个基于内存且支持持久化的key-value的NoSQL数据库,... 查看详情

如何删除与 Redis 集群中的模式匹配的键

】如何删除与Redis集群中的模式匹配的键【英文标题】:HowtodeletekeysmatchingapatterninRedisCluster【发布时间】:2019-05-1123:25:45【问题描述】:我已经尝试过这个question中的方法,但是由于我在集群模式下工作,它不起作用,redis告诉我... 查看详情

rediscluster集群选主

...策略redisserver事件模型redisclustermget引发的讨论redis3.xwindows集群搭建redis命令执行过程redisstring底层数据结构redislist底层数据结构redishash底层数据结构redisset底层数据结构rediszset底层数据结构redis客户端管理redis主从同步-slave端redis主... 查看详情

分布式缓存技术redis学习系列——redis高级应用(集群搭建集群分区原理集群操作)

...与锁、持久化)》本文我们继续学习redis的高级特性——集群。本文主要内容包括集群搭建、集群分区原理和集群操作的学习。Redis集群简介Redis集群是3.0之后才引入的,在3.0之前,使用哨兵(sentinel 查看详情

redis集群高可用架构(代码片段)

Redis集群高可用架构1、Redis高可用集群1.1、Redis高可用集群模式和哨兵模式方案比较1.2、Redis高可用集群搭建2、Java操作Redis集群3、Redis集群原理分析3.1、槽位定位算法3.2、跳转重定位3.3、Redis集群节点间的通信机制3.4、Redis集群选... 查看详情

redis集群搭建

目录1集群2集群架构图3集群细节4集群搭建5.创建集群1.创建集群2.输入yes,表示按照当前这种分配进行创建3.集群创建成功出现如下提示6.查看集群状态1.连接集群加上-c3.添加主节点4.添加从节点5.删除节点6.集群在线分片7.spring... 查看详情

redis集群cluster集群

...压力,在3.0版本Redis-Cluster出现解决了这个问题Redis-Cluster集群特点:  1)由多个Redis服务器组成的分布式网络服务集群  2)集群之中由多个Master主节点,每一个主节点都可读可写  3)节点之间相互通信,两两相连  4)R... 查看详情

redis集群环境搭建(代码片段)

一、RedisCluster(Redis集群)简介redis3.0版本之前只支持单例,在3.0版本及以后才支持集群redis集群采用p2p模式,是完全去中心化的,不存在中心节点或者代理节点。redis集群是没有统一的入口的,客户端(Client)连接集群的时候连... 查看详情

redis单机,主从集群,哨兵集群,分片集群的搭建(代码片段)

...丢失问题3.1RDB持久化3.2AOF持久化3.3RDB和AOF比较4.Redis主从集群解决并发不足问题4.1.集群结构4.2.准备实例和配置4.3.启动4.4.开启主从关系4.5.测试4.6.数据同步原理5.Redis哨兵集群解决故障恢 查看详情

zookeeper,eureka和redis集群架构

目录ZOOkeeper,Eureka和Redis集群有什么区别?zk集群Eureka集群Redis集群过半数存活原则ZOOkeeper,Eureka和Redis集群有什么区别?zk集群Eureka集群Redis集群过半数存活原则 查看详情

zookeeper,eureka和redis集群架构

目录ZOOkeeper,Eureka和Redis集群有什么区别?zk集群Eureka集群Redis集群过半数存活原则ZOOkeeper,Eureka和Redis集群有什么区别?zk集群Eureka集群Redis集群过半数存活原则 查看详情

redis集群搭建最佳实践

要搭建Redis集群。首先得考虑以下的几个问题;Redis集群搭建的目的是什么?或者说为什么要搭建Redis集群?Redis集群搭建的目的事实上也就是集群搭建的目的。全部的集群主要都是为了解决一个问题,横向扩展。在集群的概念出现... 查看详情

redis集群部署(代码片段)

redis-5.0.4集群搭建redis-cluster介绍?1:redis是一个开源的keyvalue存储系统,受到了广大互联网公司的青睐。?2:redis集群采用P2P模式,是完全去中心化的,不存在中心节点或者代理节点;?3:redis集群是没有统一的入口的,客户端(clie... 查看详情

redis客户端集群

   1、Redis集群一般分为两类,即3.0版本后的服务端集群实现,3.0版本前的客户端集群实现,服务端集群即RedisCluster(官方实现),采用slot槽的概念(分片,所有服务端redis实现共享16384个slot,集群的搭建、新增、删除... 查看详情

如何安装redis集群

参考技术A创建目录,copy配置文件如何安装Redis集群修改配置文件按照此方式修改7001~7005的配置文件,注意修改端口号。如何安装Redis集群启动各个实例如何安装Redis集群创建集群现在我们已经有了六个正在运行中的Redis实例,接... 查看详情

windows环境搭建redis集群

 一、Windows环境搭建Redis集群参考资料:Windows环境搭建Redis集群 二、Linux环境搭建Redis集群参考资料:RedisCluster的搭建与部署,实现redis的分布式方案 查看详情

redis高可用集群搭建

redis高可用集群搭建_恶魔的复活的博客-CSDN博客_redis集群搭建 查看详情

redis高可用集群搭建

redis高可用集群搭建_恶魔的复活的博客-CSDN博客_redis集群搭建 查看详情