Pika 是一个可持久化的大容量 redis 存储服务,兼容 string、hash、list、zset、set 的绝大部分接口(兼容详情),解决 redis 由于存储数据量巨大而导致内存不够用的容量瓶颈。用户可以不修改任何代码从 redis 迁移到 pika 服务。由于单机 pika 容量受限于单块硬盘容量的大小,360 公司业务和社区对分布式 pika 集群的需求越来越强烈,因此我们推出了原生分布式 pika 集群,发布 pika 版本 v3.4。与 pika+codis 集群方案相比,pika 集群不需要额外部署 codis-proxy 模块,同时由于 codis 对 pika 创建和管理 slot 操作的支持并不友好,需要运维人员大量介入。
以 3 个 pika 节点的集群为例,集群部署结构如上图所示:
为了对数据按照业务进行隔离,Pika 集群引入 table 的概念,不同的业务数据存储在不同的 table 中。业务数据按照 key 的 hash 值存储到对应的 slot 上面。每一个 slot 会有多个副本,从而形成一个 replication group。replication group 中的所有 slot 副本具有相同的 slot ID,其中一个 slot 副本是 leader,其他副本为 follower。为了保证数据的一致性,只有 leader 提供读写服务。可以使用 pika manager 可以对 slot 进行调度迁移,使数据和读写压力均匀的分散到整个 pika 集群中,从而保证了整个集群资源的充分利用并且可以根据业务压力和存储容量的需要进行水平扩容和缩容。
pika 使用 rocksdb 作为存储引擎,每个 slot 会创建对应的 rocksdb。pika 中的每个 slot 都支持读写 redis 5 种数据结构。因此数据迁移的时候会特别方便,只需迁移 pika 中的 slot 即可。但同时也存在资源占用过多的问题。目前的 pika 在创建 slot 的时候会默认创建 5 个 rocksdb,分别来存储 5 种数据结构。在 table 中含有大量 slot 或者创建大量 table 的时候会使单个 pika 节点含有多个 slot,进而创建过多的 rocksdb 实例,占用了过多系统资源。在后续版本中一方面会支持创建 slot 的时候根据业务需要创建一种或几种数据结构,另一方面会持续对 pika 中的 blackwidow 接口层进行优化,减少对 rocksdb 的使用。
我们把 proxy 内嵌的 pika 中,不需要单独部署。与 redis cluster 相比,客户端不需要感知 proxy 的存在,只需像使用单机一样使用集群。可以把 pika 节点的服务端口挂载到 LVS 中,实现压力在整个集群的负载均衡。
pika 中 replication manager 模块负责日志的主从同步。为了兼容 redis,pika 支持非一致日志复制,leader slot 直接在 db 中写入数据而无需等待从 follower slot 的 ack 应答。同时也支持 raft 一致性协议方式的日志复制,需要满足收到大多数副本的 ack 才写入 db。
非一致日志复制
在非一致场景下处理流程如下:
一致性日志复制
在一致性日志复制场景下:
我们在 codis-dashboard 的基础上二次开发了 pika manager(简称 PM),作为整个集群的全局控制节点,用来部署和调度管理集群。PM 里保存了整个集群的元数据及路由信息。
pika 原生集群的推出解决了单机 pika 受限于磁盘容量的限制,可以按照业务的需求进行水平扩容。但仍然有一些缺陷,如基于 raft 的内部自动选主功能的缺失,基于 range 的数据分布,及监控信息的展板等功能。后续版本我们会一一解决这些问题。
领取专属 10元无门槛券
私享最新 技术干货