作者|董道光,喜马拉雅缓存技术专家
KV存储是喜马拉雅最重要的基础组件之一,每天承载着千亿级的请求量。面对公司成百上千的业务,我们怎样满足不同用户对不同场景下的KV存储需求?我们又是如何做到服务的高可用,为业务的稳定性保驾护航的?下面,我会给大家介绍下喜马拉雅的KV存储演进之路,主要内容包括:
- 喜马拉雅KV存储的演进历史
- 如何用自研+社区的方式做自己的缓存系统
- 该系统的运行原理及未来规划
喜马拉雅KV存储发展历程
Redis主从模式
和早期的大多数互联网公司一样,喜马拉雅刚开始的缓存就是简单的主从架构模式,客户端通过vip连接到master节点,master节点挂掉时,漂移vip到slave机器上来保证高可用。这种架构的优点是部署流程简单、易维护,但缺点也很明显,就是QPS和容量受限,因为单个redis的QPS一般不超过10w,数据量一般需控制在10GB内(数据量大,故障重启比较耗时)。
针对上面的问题,大家肯定都想到了既然一个redis不行,那就用多个redis一起扛,类似mysql的分库分表,于是之后就有了客户端sharding模式的架构,即在客户端对key做hash取模,然后打到后端不同的redis节点上。这种架构的优点是可以解决QPS容量受限的问题,但缺点也很致命:无法做到弹性扩容,并且增加删除节点时,客户端代码也要跟着一起改动,非常不方便。严格意义上来说,这种架构根本不能算是集群解决方案。
那么,针对上述问题,业界有没有比较好的解决方案呢?答案是有的。
集群模式选型
2016年时,redis的集群解决方案还不是很多,我们调研了当时业界比较流行的三种解决方案:
Redis Cluster:优点是官方正版,去中心化,组件少,部署简单;缺点是系统高度耦合,升级困难,缺少大规模生产环境验证(当时cluster刚出来没多久)。
Twemproxy:推特开源,proxy代理,无法平滑扩容缩容,运维不够友好。
Codis Redis:豌豆荚开源,proxy代理,兼容Twemproxy,性能优于Twemproxy。平滑扩容缩容,可视化管理界面。产品成熟,很多公司已经在生产环境使用。
基于上述分析,我们最终选择了Codis Redis作为Redis的集群解决方案。下面就让我们一起来了解下Codis Redis。
Codis Redis
Codis Redis使用Proxy做代理,后端连接多个Redis分片,客户端连接proxy,当proxy接收到命令时,会对key做CRC32取模,然后打到后端不同的Redis分片上。Codis Redis还使用ZooKeeper做服务发现,当集群中新增一个proxy时,会自动注册到ZooKeeper上, Jodis客户端会监听节点新增事件,然后更新proxy列表。Codis Redis自带web管理页面Codis-fe,并且支持对sentinel哨兵(高可用组件)的管理,所以在当时来看还是非常好用的。
那么,Codis Redis如何实现弹性扩容呢?Codis将所有key分配到1024个slot中,每个分片负责一批slot。如下图,当集群只有2个分片时,group-1负责0~511的slot,group-2负责512~1023的slot。
当集群需要从2个分片扩容到4个分片时,codis首先将group-1中256~511的slot数据迁移到group-