挚文集团于 2011 年 8 月推出了陌陌,这款立足地理位置服务的开放式移动视频社交应用在中国社交平台领域内独树一帜。陌陌和探探作为陌生人社交领域的主流应用,涵盖了多种核心业务模块,包括直播服务、附近动态功能、即时通讯(IM)业务以及增值服务等,每个业务场景都具有其独特性和挑战。
在本文中,陌陌数据库负责人冀浩东将聚焦探讨陌陌的 KV 系统架构选择思路,并深入解析如何进行此类系统的甄选决策。他将进一步分享陌陌团队在采用 OceanBase(OBKV)过程中所经历的探索与实践经验。
在陌陌众多业务场景中,直播业务占据了显著位置,其特点就在于随时可能出现的流量突发场景。由于低延时和高并发的需求,直播场景对数据库系统的实时处理能力提出了较高要求。平台需要确保在大量用户同时在线观看和互动时,数据能够被及时、准确地处理和分发。
附近动态功能则涉及到用户的地理位置信息、活动轨迹以及社交关系等复杂数据。这类数据会迅速积累,并随着时间的推移形成大规模的数据集。数据具有明显的冷热分层特性,即某些数据在某一时刻可能会成为热点,如当某用户发布的帖子引发热议并成为热门话题时。这要求系统能够有效管理并快速响应热点数据的访问需求。
IM 业务场景的核心特点是低延迟和高并发通信。信息的送达时间必须精确,对实时性有极高的要求。为了保证用户体验,应用程序需要确保消息能够即时、可靠地在用户之间传递。
增值服务则主要侧重于数据的一致性和实时性。在处理用户购买、赠送虚拟物品或享受会员特权等操作时,系统需要确保数据的准确性并及时更新用户账户状态。同时,为了提供优质的增值服务,实时性也是不可或缺的因素,例如实时计算用户的积分、等级或者权益等。
陌陌和探探在运营这些业务场景时,都需要强大的数据处理和管理系统来应对各种特性和挑战,以确保为用户提供高效、稳定且满足个性化需求的社交体验。针对以上的业务场景,我们应该如何选择 KV 系统呢?
在公司的成长过程中,存储选型通常会经历四个阶段。
初始阶段,公司的主要目标是能够运行起来。在创业初期,基于新开发的 App 进行运营工作时,由于业务能力可能还未成熟,为了应对快速迭代的业务需求,对系统的期望不会过高。只需要确保技术层面能够满足基本的业务需求并逐步演进即可。在这个阶段,常见的架构选择包括 Redis 主从架构和 Redis Cluster 等原生架构。
Redis 主从集群架构的优势在于可以迅速构建主从集群或分片集群,并且许多设计可以直接在客户端操作。然而,这种简单的操作方式可能导致设计与客户端业务代码的高度耦合,不利于后期的弹性扩容。
相比之下,Redis Cluster 集群架构支持动态扩容和高可用性。然而,使用 Redis Cluster 时,业务依赖客户端感知节点变更。如果客户端未能正确处理节点变更,可能会导致服务中断或业务性能下降,因此对于对错误敏感的业务,Redis Cluster 可能会引入额外的复杂性。尽管 Redis Cluster 具有去中心化、组件少、提供 Smart Client 以及支持水平扩展等优点,但也存在批处理功能不友好和缺乏有效流控机制等问题。
进入第二阶段,随着公司的发展和用户数量的增长,需要架构具备快速扩展的能力。这一阶段的代表性架构例如 Codis、Twemproxy 等基础性 Redis分片架构。其中,Codis提供了服务端分片方案、中心化管理、故障自动转移、节点水平扩展(1024 槽位)、动态扩缩容,以及支持 pipeline 和批处理等功能。然而,Codis的当前版本较为陈旧,官方仅提供 3.2.9 版本,更新版本需要自行修复和适配,且由于组件多、资源消耗大。
第三阶段,随着业务的进一步发展和公司进入相对稳定期,可能会发现先前急于扩张时遗留了一些问题。例如:是否过度使用内存,数据是否可以冷热分层等。这些问题需要重新检验和优化。这个优化过程是第三阶段的重点。在这个阶段,常见的持久化架构选择包括 oneStore-Pika、Tendis 和 Pika 等。
最后,在第四阶段,公司业务和技术可能已经进入了深度复杂的领域,简单的优化调整可能无法带来显著的收益,甚至可能出现无法进一步优化的情况。这时,可以通过引入更稳定的架构或者采用新的解决思路来应对挑战。我们个人推荐考虑多模态架构,它能够适应多种数据类型和工作负载,提供更大的灵活性和优化空间。
总的来说,公司在不同发展阶段的存储选型应根据业务需求、技术成熟度、成本效益以及未来的扩展性和优化空间等因素进行综合考虑和决策。随着公司的发展和业务复杂性的增加,存储架构也需要不断进化和优化,以确保系统的稳定、高效和可持续发展。
针对当前公司的业务状况,陌陌面临的最显著挑战在于集群规模的不断增长。当单集群分片数量超过 1000 个,数据量超过 10TB,以及 QPS 超过 100 万时,现有的 Codis 架构和 Redis Cluster 架构已然无法满足需求,达到了其承载能力的极限。
为了解决这一瓶颈问题,公司自主研发了一款名为 oneStore 的存储产品。(如下图所示)。这一架构经过了分阶段的优化和改进过程,旨在突破原有的限制,以适应更高的分片数量、更大的数据量以及更密集的查询请求。通过 oneStore 架构,陌陌力求实现业务扩展的无缝对接和性能的大幅提升。
第一阶段,提供服务端 Proxy 方案,并通过自主研发的 oneStore Watcher 哨兵组件进行架构精简。这样一来,只需要部署一套哨兵集群,就能有效地管理一个业务区域。
第二阶段,提供客户端 SDK 方案。虽然服务端 Proxy 方案表现优秀,但随着业务的稳定,公司着眼于降本增效。直接使用客户端 SDK 方案,感知集群拓扑变化,并且通过 SDK 直连后端 Redis 地址,这样可以去除服务端 Proxy 组件,节省技术资源开销。然而,我们并没有完全摒弃服务端 Proxy 方案。因为目前陌陌的客户端 SDK 方案仅支持 Java 和 C++,对于 PHP、Python 等其他语言的用户,仍需要通过服务端 Proxy 访问数据源。这两种方案的成功运用,帮助我们统一了公司层面 Redis 的接入方式,并显著提升了机房迁移的效率。
随着业务的进一步稳定,陌陌开始从成本角度进行优化,选择 Pika 替代部分请求量不高的 Redis 集群,再提升架构的持久化能力(如下图所示)的同时降低存储成本。然而现阶段 Pika 主要用来存储一些相对较冷数据,对于热数据的处理性能仍有待提高,后续团队也会持续关注并努力提升这一方面的性能。
总的来说,目前陌陌还面临一些需要解决和优化的场景:
单机多实例之间互相影响的问题:陌陌迫切需要解决单机多实例之间相互影响的问题,以确保各个实例的稳定运行和高效协作。这涉及到系统的整体稳定性和协同性,需要有针对性的优化和调整。
数据持久化支持:陌陌计划增强数据持久化的支持能力,以实现完整的数据持久化解决方案,以保障数据的完整性和可靠性。不仅仅局限于冷数据,而是要覆盖更广泛的数据类型,以确保数据的完整性和可靠性。这将是系统长期稳定性的一个重要保障。
所以,陌陌需要通过一个简单可靠可扩展的 KV 系统来解决以上问题。
OBKV 是 OceanBase 数据库提供的通过 API 接口访问 Table 模型 Hbase 模型的能力。陌陌之所以选择 OceanBase(OBKV),主要看中其两大优势。
第一,性能更好。OceanBase(OBKV)基于 Table 模型构建,与 Redis 数据结构持久化方案这个典型的表模型匹配,且性能比传统持久化存储更强 ,能构建更丰富的数据结构。
下图是 OceanBase(OBKV)在大量写数据的场景(TPS 17000),由于不同阶段都有任务在写数据,可以看出 TPS 非常陡峭,并且响应延时在 2 毫秒以下,事务的响应时间明细与预期是相对应的。
下图为 CPU 监控图,可以看到 CPU 使用率在 10% 以下,相对稳定。MemStore 的使用比例也是正常的,在 24% 以内,波动范围非常小,符合预期。
整体来看, OceanBase(OBKV) 生产环境波动小,资源占用稳定。
第二,稳定性高。OceanBase(OBKV) 基于 OceanBase ,存储引擎经过丰富的大规模 TP 场景验证,能提供高并发、低延时的能力。从下图OceanBase(OBKV) 的多租户功能可见其稳定性。黑色线代表 OceanBase(OBKV)租户,蓝色线的租户是 MySQL 租户。在 11:30 左右发起压测以后,OceanBase(OBKV) 租户的响应正常, MySQL 租户也没有受到影响。从服务器层面来看,CPU 负载是因为压测而上升的,而 MySQL 租户并不受影响。
因此可以得出,多租户功能能够有效解决单机多实例的相互影响问题。下图展示了是线上 MySQL 生产租户的表现,TPS 为 5000时,整体表现非常稳定。CPU 和内存使用波动较小,符合预期。
此外,我们能够便捷地通过 KV 接口将数据存入数据库,并运用 SQL 进行数据查询。OceanBase(OBKV)进一步增强了这一便捷性,它支持二级索引以及服务端TTL功能,这有助于显著简化上层服务架构的设计。尽管如此,OceanBase(OBKV)也存在一定的局限性,如仅提供单机事务处理能力;若要开启分布式事务支持,则可能会影响到系统在高并发环境下的性能表现和低延时响应能力。但鉴于当前陌陌业务的需求,我们认为 OceanBase(OBKV)的单机事务能力完全符合要求,并因此共同构建了结合 OceanBase(OBKV)- Redis 储存方案。
陌陌与 OceanBase 开源团队共同打造了一个内部代号为 modis 的项目。该项目整体架构涵盖了接入层、数据结构层、缓冲层、存储层以及管理平面等多个层次(具体可参考下图)。值得注意的是,缓冲层在未来的规划中将用于有效解决热点读取及大 KEY 问题的挑战;而在存储层方面,陌陌将对其进行标准化抽象设计,构建出标准的 Storage 结构,以便能够灵活接入包括但不限于 OceanBase(OBKV)在内的多种存储解决方案。
在测试评估过程中,我们将 Pika 数据(总计 158GB)成功迁移到 OceanBase(OBKV)-Redis 集群后,存储占用空间显著减少至 95GB,这一举措带来了存储成本的显著优化,总体上节约了大约 40% 的存储成本。
为了评估性能表现,我们特意构建了一个专门的测试环境(具体规格参见下图),并在该环境中模拟了不同并发线程场景以观测其峰值性能情况。
基于多租户管理的理念,我们不会对单一租户分配过多资源,而是优先观察各个租户在使用过程中哪个率先达到性能瓶颈,并据此计算单核的 QPS。当前,陌陌提供的标准规格为 12C40G 内存。未来,为了更好地适应业务需求的变化,可能会推出更小规格的配置方案,例如 4C8G 或 8C16G 等规格,这些决策将完全取决于实际业务的具体需要。
下图展示了 128 个线程数 QPS 70000 情况下 OceanBase(OBKV)-Redis 的性能表现:
P90 响应延迟为 1.9 ms;
P95 响应延迟为 2.2 ms;
P99响应延迟为6.3 ms;
平均计算下来,单核读写比例是 4:1,此时单核能力接近 6000 QPS。
此外,在运维管理方面,陌陌深入对比了 OceanBase(OBKV)、Pika 以及 TiKV 在日常运维操作中的特性差异。目前,只有 OceanBase(OBKV)提供了原生的多租户支持功能,这一优势有效地解决了我们在单机部署多实例时所面临的相互干扰的问题。值得一提的是,OceanBase(OBKV)凭借其完备的图形化界面管理工具和参数变更即刻生效的特点,对于长期从事数据库运维工作的人员来说,无疑是一个极其贴心且高效的解决方案。
总的来说,OceanBase(OBKV)-Redis 实现了性能的显著提升、更少的磁盘使用以及运维管理的极大简化。这主要得益于 OceanBase(OBKV)-Redis 的几个优势。
多租户隔离,解决单机多实例互相影响的困境;
存储成本更低。通过 Encoding 框架 + 通用压缩 ,进行表模型存储;
性能更高。将请求过滤直接下压存储,不用序列化以及反序列化,支持服务端 TTL。
当前阶段,OceanBase(OBKV)-Redis 集成了对 String、Hash 和 Set 等核心数据结构的强力支持,其命令覆盖范围已超过 93%,并且预计在 2024 年第一季度将完成对常用管理命令的全面兼容,并同步实现容器化部署及二级缓存功能的集成;同时,我们还计划将其与 CDC 方案进行深度融合。在接下来的 2024 年第二季度,研发团队将持续发力,以期顺利完成数据迁移功能的研发工作,并进一步引入数据分层技术。
对于 OceanBase(OBKV)-Redis 的未来展望,我们充满信心且满怀期待,期望能够早日实现对数据全生命周期的精细化管理。特别是当公司迈入第四发展阶段,业务和技术挑战也随之深入时,稳定性和创新性将成为并驾齐驱的关键要素。因此,陌陌对多模生态体系寄予厚望,它有望通过解决存量问题和降低成本来赋能企业。