樊建 陈营 葛宝磊/华泰证券股份有限公司
摘要:Redis Cluster作为最热门的开源分布式缓存,在券商领域会有怎样的应用场景?本文从华泰证券的应用现状出发,介绍了Redis Cluster在华泰证券的大规模实践经验。
Redis是一个开源(BSD许可)的内存Key-Value存储系统,它可以用作数据库、缓存和消息中间件。它支持多种类型的数据结构,如:字符串、散列)、列表、集合、有序集合与范围查询等。 Redis内置了复制、LRU驱动事件、事务、磁盘持久化等特性,并通过Redis哨兵(主从模式)和自动分区(Redis Cluster模式)提供高可用性。
官方的Redis Cluster推出前,常见的Redis Cluster开源方案主要是Codis和Twemproxy,两者均采用Proxy的方式实现分布式。通过引入Proxy层来屏蔽底层数据的分布,可以简化客户端的实现,但使得集群架构变得复杂,维护成本上升。Redis从3.0开始支持自动分区,采用无中心节点方式实现Cluster模式。访问Redis Cluster时,无需Proxy代理,具备Smart特性的客户端直接与Redis Cluster中的每个节点连接。
Redis引入Cluster模式带来的优势在于:
1.可靠性:具有分区机制、副本机制和自动容错机制;
2.高性能:保证了Redis高吞吐的前提下,可线性扩展到上千个节点;
3.可扩展性:基于分区的自动扩容、缩容,客户端透明的数据迁移。
目前,Redis在互联网、金融、传统行业内的应用已十分广泛。随着金融业接入互联网的业务增加,活动、促销、节假日、热门事件等可能带来突发数倍甚至几十倍的访问峰值的情况时有发生,Redis Cluster是抵御突发海量访问的有效手段。
Redis Cluster整体设计是比较简单的,集群架构采用无中心节点的方式实现,集群中的节点通过Gossip协议相互交换集群状态。客户端无需代理直接访问服务端,客户端通过Hash算法计算出Key对应的哈希槽,然后直接访问哈希槽对应的服务端节点。
Redis Cluster的拓扑结构如下图所示:
2015年,随着华泰证券互联网金融自主研发的大规模投入,面对海量用户并发场景,迫切需要建设统一化、服务化的分布式缓存平台。
通过对Redis Cluster、Codis及Twemproxy等开源Redis集群解决方案进行验证和对比,最终从性能、易维护、高可用等方面考虑,选择Redis 3.2.0版本的Cluster模式作为公司级缓存解决方案。Redis Cluster获得了开源社区的持续支持,功能、特性一直在迭代改进。相比之下,Codis及Twemproxy社区活跃度较低,维护成本相对较高,吞吐量也略逊于Redis Cluster。
目前,在华泰证券建设有多套Redis Cluster资源池,总体集群服务器数量20余台。在交易时段,峰值访问量超20万次/秒,服务了30个以上应用系统,包括:行情中心、涨乐财富通、互联网用户中心等,在缓存、分布式锁、内存存储、任务队列等业务场景都有应用。
如图2所示,Redis Cluster数据节点采用同城三数据中心部署方式,通常其中两个数据中心部署数量相等的机器,另一数据中心部署单台机器。为加速重做从节点的速度,主机采用万兆网卡。为保证访问缓存的延时足够小,跨数据中心之间的网络通信采用独立的万兆波分通道。
1、推荐使用Jedis2.8.x及以上版本,关闭TestOnReturn和TestOnBorrow;
2、推荐使用Jedis的JedisPoolConfig,它是对GenericObjectPoolConfig的优化版本;
3、合理使用HGETALL、SMEMBERS等O(N)操作。
1、重命名KEYS、FLUSHALL、FLUSHDB等耗时且危险的操作;
2、适度加大client-output-buffer-limitslave避免不必要的重做从节点;
3、适度加大repl-backlog-size和repl-backlog-ttl,值越大slave可丢失的时间越长;
4、AOF,关闭RDB,减少服务端fork操作造成的访问出现卡顿的现象;
5、根据实际场景配置cluster-require-full-coverage为yes,减少集群不可用的时间。
Redis cluster是分布式的Redis实现,具有一定的容错性和线性可扩展性,这些特性牺牲了以下功能:
1、不能使用SELECT命令,不支持对多个槽位内的KEY进行操作,比如MSET、SUNION;
2、发布订阅功能不推荐使用,集群规模越大,产生的网络流量越大;
3、采用Redis主从模式的应用,客户端代码需要少量的改造才能升级到Cluster模式。
开源中间件难免出现Bug及其它性能问题,大部分问题开源社区都能找到问题的解决方案,积极的跟进社区讨论是有效的避免生产事故的有效途径。在实际使用中,我们发现了多个Redis的Bug,社区均有解决方案。目前,我们已经将生产环境上部分Redis节点升级到3.2.7版本,主要因为遇到以下问题:
1、从节点同步Ziplist后,List索引更新错误,造成从节点Crash;
2、Ziplist中成员长度增长,List索引更新错误,造成主节点和从节点的AOF重写均失败,产生大量临时文件。
Redis 2.8.0版本开始引入PSYNC机制,PSYNC通过添加缓冲队列,缓存从节点断开连接期间的数据变化增量,当从节点重新连接且缓存队列未溢出时,则可避免早期版本从节点重连后必然需要SYNC操作全量同步主节点数据的问题。
PSYNC可以有效地解决网络抖动造成的从节点短暂断开连接的问题,但无法避免当主节点、从节点相继出现网络失连、重启、进程推出的情况发生后的全量数据同步和恢复,Redis 4.0引入PSYNC 2和PSYNC 3等新特性来解决相关问题。目前Redis 4.0仍处于验证阶段,需要持续验证和密切关注。
与其它开源的key-value内存存储系统相比,Redis支持的数据更加丰富,常用的value数据类型包括:字符串、哈希表、链表、集合、有序集合。同时,Redis还内置了这些数据结构的常见操作。目前,Redis的应用已经非常广泛,常见的使用场景包括:缓存热数据、计数器、队列、分布式锁、排行榜、新闻列表、评论等场景。Redis Cluster在华泰证券的新建信息系统中也得到了广泛的应用,使用的部分场景举例如下:
行情截面
某些应用场景可能需要获取某个市场或多个股票的最新行情,可以使用Redis的Hash结构来实现这个需求。示例代码如下:
添加或更新一只股票的行情
HSETMD:XSHG:STOCKTYPE “601688.SH” 17.88
获取多只股票最新行情
HMGET MD:XSHG:STOCKTYPE “601688.SH” “601689.SH”
获取某个交易所所以股票最新行情,HGETALL操作为O(N)操作,不建议频繁调用
HGETALL MD:XSHG:STOCKTYPE
K线
常见的K线为日K线或分钟K线,以日K线为例,可以使用Redis的有序集合来实现,示例代码如下:
添加某只股票2018年3月1的K线
ZADD KLINE:1DAY:601688.SH 20180301 kline_value
获取某只股票多天的K线
ZRANGEBYSCORE KLINE:1DAY:601688.SH 20180301 20180302
任务队列
任务队列用来在任务的生产者和消费者之间传递任务,实现任务的产生和任务执行模块间的松耦合。实例代码如下:
生产者生成一个任务task01
RPUSH TASK:QUEUE “task01”
消费者堵塞等待100秒等待任务,BLPOP是LPOP的堵塞版本
BLPOP TASK:QUEUE 100
随着业务的不断发展,Redis Cluster在华泰证券内部已成为核心组件。未来重点进行PaaS平台建设,加强集群自动化灾备;建立分级保障制度,对重点业务进行独立管理。目前,Redis的最新版本4.0.x解决了Redis 3.2.x版本在面对网络剧烈抖动时,偶尔会出现部分分片所在的主从节点均不可用的情况。尽早验证Redis 4.0.x版本的稳定性,制定有效的升级方案和计划,也将是未来工作的重点之一。
如果觉得我的文章对您有用,请点赞。您的支持将鼓励我继续创作!
赞6
添加新评论1 条评论
2018-07-02 18:08