网易云信架构升级实践,故障恢复时间缩至8秒

一、项目背景

网易云信是网易旗下集IM与音视频技术于一体的PaaS服务平台,为全球提供融合通信与视频的核心功能和组件,包括IM即时通讯、短信、信令等通信服务,以及RTC、直播、点播、互动直播、互动白板等音视频服务,此外,网易云信结合网易易盾推出一站式安全通信方案------安全通。由于其广泛的服务场景与多元化的业务需求,网易云信在底层架构上依赖于多元化的数据库系统。以IM通讯系统为例,该系统不仅采用了网易自主研发的关系型数据库DDB,还融合了Redis、HBase及Elasticsearch等重要组件。随着业务需求的持续增长,数据库在性能、成本控制及高可用性方面遭遇了一系列挑战。

本文中,网易云信分享了其IM通讯系统数据库的架构设计优化方案,并阐述了如何利用OceanBase 和 OBKV ,在关系型数据库及KV业务场景中升级并简化现有架构,从而在性能提升、成本节约、运维简化及高可用保障等方面取得的思考与实战经验。

目前,网易云信融合通信已接入 220 万企业开发者,全球注册应用数超 75 万,累计覆盖智能终端 SDK 数超 300 亿,月均消息量 3100+ 亿条,居行业首位,日活消息量表现突出。作为专为企业打造的融合通信的品牌,网易云信专注于文娱、社交、教育、医疗等行业,支持公有云、专属云、私有云与混合云四种部署方式。

对于如此体量的服务,数据库作为基石与支柱,扮演着极为重要的角色。随着业务规模的持续增长,我们也正在寻找一套适配网易云信业务场景的升级方案,在简化数据库系统架构、降低运维管理成本的同时,实现降本。本文将分享网易云信数据库实践和运维经验,以及网易云信选型OceanBase背后的实践与思考。

二、网易云信数据库架构现状:需求复杂,种类繁多

在网易云信中,通讯和视频服务都高度依赖数据库,尤其是IM通讯系统。在IM通讯系统中,数据库种类较多。包括关系数据库DDB、缓存数据库Redis,以及HBase和Elasticsearch等。

1、DDB

DDB是网易自研的分库分表中间件,目前在网易内部被广泛应用。不仅网易云信,网易云音乐、有道等众多产品也都深度依赖这套系统。在云信IM系统中,DDB主要用于存储账号、用户关系、群组关系、离线消息等核心的结构化数据。

DDB是一个很经典的分库分表架构。接入层我们称为QS服务器,这是一个SQL-proxy,QS服务器的后端则是实际的存储节点,通常是MySQL。客户端连接QS服务器支持两种方式,一种是通过挂载四层负载均衡器,如nlb或阿里云上的slb,来实现对QS的负载均衡和高可用,此外,对于Java程序,DDB还额外提供了lbd-driver驱动,它的优势在于能直连QS服务器,从而在QS上下线管理以及故障转移上更加平滑,此外因为省去了nlb组件,也降低了网络延迟。

DDB是一套完整的解决方案,用于管控的master,元数据存储的sysdb、以及用于高可用切换的ddb-switcher,此外通过ndc这样的数据同步工具以及owl的数据平台,可以统一管理ddb集群,包括表变更、扩缩容等等。

2、Redis

redis在网易云信IM系统中占有重要角色,支撑着多种业务场景,我这边简单选取几个代表性的场景。

1)数据库缓存

第一个场景是数据库缓存,基于自研数据库缓存框架,主要依赖简单的kv读写操作,如set/get/del。

这个场景的特点是读多写少,且读操作的TPS很高。

2)在线状态缓存

第二个场景是在线状态管理,用于记录账号和设备的在线状态,使用redis中的hash结构记录多端登录和实现复杂的多端互踢策略,也是消息分发时的关键组件。简单讲,用户登录时系统会进行在线状态的写入与更新,而发送消息时则需查询在线状态。

这是一个典型的读多写多场景,尤其在处理大群消息或批量消息发送任务时,读操作的TPS会显著上升。

3) 漫游消息

第三个典型场景是漫游消息,从用户角度来看,它主要用于实现最近消息的多端同步功能。为实现这一功能,我们采用了redis中的zset结构实现先进先出的最近逻辑。

该功能的一个显著特点是,由于需要存储最近发送的消息以便进行同步,因此其存储开销相对较大

3、HBase和Elasticsearch

此外,我们还引入了HBase和Elasticsearch数据库,主要用于存储和查询历史消息。

HBase的row-key全局有序的特点,非常适合适合根据时间进行历史消息分页查询的场景;而Elasticsearch被用于关键词检索等更复杂的搜索需求,为了降低存储开销,在Elasticsearch中我们并没有直接存储消息的完整内容,最终的搜索结果指向的是HBase中row-key。除了消息之外,用户和关系的检索等也会用到es相关的能力。

四、问题和挑战:业务需求与特定场景带来多样挑战

前面介绍了云信的数据库使用背景及现状,当前我们在使用数据库的过程中也面临一些问题和挑战。

1、DDB

首先,在关系数据库方面面临以下几个问题。

**第一,性能瓶颈问题。**尽管我们使用的分库分表架构已经相当稳定,并且依赖于内部强大的owl平台,能够自动化完成许多运维工作,如自动扩缩容、在线表变更等,但在某些特定场景下,我们仍然遇到一些瓶颈。为了进一步提升业务的灵活性和应对未来可能的扩展需求,我们希望能够引入原生的分布式数据库。这样不仅可以解决当前的性能瓶颈,还能为业务带来更多的弹性和可扩展性,这是我们最初的诉求。

**第二,资源利用率问题。**DDB基于MySQL存储作为数据节点,其B+tree结构既有优势也有局限,这是众所周知的。在云环境下,我们期望在某些场景中能提高磁盘利用率,以实现降本增效。

**第三,资源隔离功能。**DDB已提供一定程度的资源隔离能力,通过配置policy或者schema来实现。这些隔离策略能满足大多数业务场景的需求。然而,在某些特定的业务场景中,我们期望有更精细化的资源控制机制。现有的隔离机制可能是库表级别的,但我们希望它能进一步细化。对于云信这样一个多租户的PaaS系统来说,更细粒度的资源控制是很有必要的。

2、redis

最初我们采用了开源的redis-cluster集群部署方案。Redis-cluster本身是多节点且支持水平扩缩容的,在初期单集群即可很好的满足云信的单一业务需求。然而,随着业务的持续增长,由于redis-cluster单集群节点数的上限(我们单集群一般不超过100主100从),我们遇到了单集群下的内存容量瓶颈和QPS容量瓶颈。

为了突破这些瓶颈,我们开发了一个redis代理,以实现更灵活的水平扩展。这个代理服务可以将多个Redis-cluster集群使用分片的方式作为一个整体透明的对外提供服务,从而突破单集群的规模上限。此外,为了更平滑在多个集群之间迁移数据,我们还在redis代理上实现了双写功能。

然而伴随业务规模不断扩大,云信的集群数量也随之增加,这让我们开始思考如何降低成本。特别是针对漫游消息这一业务场景。

漫游消息用于在相同账号的不同设备之间同步最近n天的消息,因此它有一个显著特点,用户通常会频繁读取最近的消息,而几天前的消息则读取较少。针对其特点,我们实现了一个冷热数据分离的存储策略。具体来说,我们将热数据存储在Redis中,以便快速访问;而冷数据则被持久化到HBase中。之所以选择HBase作为冷数据的存储介质,主要是因为当时我们有一套现成的hbase集群,dba也有hbase的运维经验,此外hbase的扩展性也满足了我们业务增长带来的扩容需求。

我们发现冷热数据分离策略的效果相当不错。随即便开始思考如何将其打造得更加通用,不仅仅局限于漫游消息这一场景。为此,我们先将冷热数据分离功能中将redis设置为可选,以适应那些TPS要求不那么高、希望所有数据都直接持久化在磁盘上的场景。

不久我们意识到持久化的KV存储不应局限于HBase这一种方案。因此,我们抽象出了一套通用的接口,使得替换存储方案变得更加简单灵活。这一改动上线后,云信的系统成功接入了更多业务,如在线状态发布订阅、云端会话列表等功能,都逐渐整合到了这套方案中。

值得一提的是,我们还开源了与这些功能相关的代码(开源地址:https://github.com/netease-im/camellia),有兴趣的朋友可以进一步了解。

目前线上我们主要使用hbase作为后端kv存储,然后由于其架构特性,宕机后的恢复时间可能会相对较长,基本要分钟级别。

另外,当我们通过proxy将Redis协议转换为KV协议时,会涉及将单个key的数据映射到多条kv的情况。这种转换过程中,数据不一致的风险是不可避免的,尽管并非所有场景都对数据一致性有严格要求,但这种风险确实存在。

此外,proxy与KV存储之间的映射也会带来proxy和kv-server之间的多次网络I/O,对性能造成一定的损耗。尽管我们做了很多优化工作来减少网络I/O,但显然无法完全覆盖所有场景,性能损耗问题依然存在。

3、hbase

我们以历史消息存储这一核心场景为例。

起初,我们选择使用单个HBase集群来存储所有的历史消息数据,考虑到数据规模比较大,为了节约成本,便采用了hdd磁盘作为存储介质。然而,随着数据量的不断增长,HBase也面临了一些挑战,特别是当某个节点出现故障后恢复周期相对较长,可能需要数分钟甚至数十分钟,这对业务的稳定运行造成了不小的影响。

为了应对这些挑战,我们后来决定采用双集群方案。在这个方案中,我们部署了两个HBase集群:一个是基于hdd的全量数据集群,另一个是基于ssd的小规模集群。ssd集群用于存储最近一年内的消息,以提供更快的读写速度;而超过一年的消息则存储在hdd集群中,以节约成本。

对于写操作,我们采用双写策略,确保数据同时写入两个集群。对于读操作,如果查询的是最近一年的消息,则直接从ssd集群中读取;如果需要查询超过一年的消息,我们会从hdd集群中检索,并在业务层进行合并后返回结果。为了确保双写操作的一致性,我们引入了Kafka作为中间件。当向两个HBase集群写入数据时,如果某个集群写入失败,我们会通过Kafka记录这条失败的写入命令,并触发重试机制,以确保两个集群最终达到一致状态。

双集群方案对提升整个系统的稳定性有非常大的帮助,但并没有解决所有问题。

比如尽管我们已经将热数据迁移到了速度更快的ssd上,但HBase的故障恢复时间依然是一个需要重视的问题。虽然相比使用hdd时,恢复时间已经大大缩短,但分钟级别的恢复时间对于实时性要求极高的业务来说,仍然可能带来不小的风险。

此外,随着业务的不断扩张,ssd上的HBase集群所承受的读流量也在持续攀升。最初的设想中,在一个集群出现问题时,可以迅速切换到另一个节点以维持服务。然而,随着业务量的不断增长,特别是在高峰时段,这种切换策略变得愈发不可行。具体来说,如果ssd节点发生故障时,切换到hdd集群是一个比较艰难的抉择,因为我们不确认hdd集群是否能承担起所有流量,因此更多时候可能我们只能等待故障节点自行恢复,而这段等待时间,对于业务而言,可能就意味着服务的有损。因此数据库恢复时间已经成了制约服务稳定性进一步提升的关键。

五、技术选型:网易云信需要怎样的数据库?

鉴于上述数据库的这些痛点,我们开始寻找更符合业务需求的数据库。

在进行数据库选型的过程中,我们主要从兼容性和稳定性、平台统一性、成本、性能、高可用性、社区方面着重进行考量。

**第一,稳定性和兼容性。**这是我们着重考虑的因素。首先,稳定性至关重要,特别是对于云信的To B业务来说。鉴于云信拥有庞大的客户群体,任何微小的服务波动都可能迅速引发客户反馈,进而给前向团队和研发团队带来巨大压力。因此,稳定性无疑是数据库选型中的首要考量。其次,兼容性同样不容忽视。我们期望新数据库能够兼容现有mysql协议,以便业务能够顺利迁移,无需进行大规模修改。这样不仅能降低迁移成本,还能确保业务的连续性和稳定性。

第二,平台的统一性。如上文所述,当前许多数据库都具备多模和多功能的特点。我们期望新的数据库平台能够适应云信的多种业务场景,这样,在运维过程中,我们就能因为使用同一套系统而简化工作,进而降低运维成本。

第三,降本增效,特别是在数据存储方面。我们目前线上的数据库现状是,相较于存储需求,CPU资源往往相对闲置。经常出现的情况是,CPU还未充分利用,磁盘空间却已耗尽,且无法再增加磁盘。这时,云信不得不进行扩容。因此,如果能够通过利用CPU资源来换取存储成本的降低,对我们来说将是非常划算的。

**第四,性能方面。**虽然目前的DDB或HBase在性能上并未出现明显的瓶颈,但如果新数据库能进一步提升性能,那对我们来说无疑是更好的选择。

第五,高可用性的能力。这是我们曾经遇到问题,也是最希望得到改善的方面,特别是HBase。我们期望新数据库具备可控的故障恢复时间,这能显著提升云信服务的整体稳定性。稳定性不仅体现在日常运行的无故障上,更体现在故障发生后的快速恢复上。恢复速度越快,云信的服务中断时间就越短,对于To B业务来说,这直接关联到成本节约。

**第六,社区。**我们期望使用的数据库,是一个社区活跃、功能持续迭代的现代数据库。这样,未来一旦我们有新的需求,能得到迅速响应和及时满足,这是我们非常看重的一点。

六、网易云信业务场景下 OceanBase 的优势:多场景降本提效

基于上述关于数据库技术选型的考量,OceanBase在网易云业务场景中展现出显著优势。

1、关系数据库

首先对于关系数据库来说:

l **兼容MySQL协议。**以关系数据库为例,我们特别欣赏OceanBase社区版对MySQL协议的兼容性,便于业务几乎无需修改即可平滑迁移。同时,我们的使用方式也无需做出特殊调整,大大简化了部署和运维过程。

l **成本优势,**关于这一点,我们有坚实的数据支持,在后文中会详细展示。在采用OceanBase之前,我们曾对MySQL 8.0版本与MySQL 5.7版本进行测试、对比,虽然前者在压缩能力上有所进步,但与OceanBase相比,压缩效率仍显不足。

l 高可用能力。与DDB相比,OceanBase同样具备出色的高可用性能。然而,DDB的故障恢复时间依赖于DDB-switcher这一高可用切换工具,在最慢的情况下可能需要超过1分钟。相比之下,OceanBase的故障恢复时间可以缩短至8秒,这一优势在我们多次实际测试中得到了验证。

l 原生分布式能力。与DDB这类分库分表中间件相比,OceanBase在扩缩容时数据迁移更加高效。虽然DDB也能实现一定程度的自动化,但在资源依赖和操作流程上,OceanBase显然更为便捷。

l **多租户能力。**对于云信这样的PaaS平台,用户众多且使用习惯各异,有时难免出现个别用户行为异常,可能影响到整个系统。此时,OceanBase的多租户资源隔离能力就显得尤为重要。通过OceanBase,我们可以将云信业务中的不同租户数据隔离到各自的数据库实例中,实现资源的独立调度和管理。这样,即使某个租户出现异常行为,也不会波及其他租户或整个系统,从而显著提升服务的稳定性。这一底层逻辑的设计,充分体现了OceanBase在多租户资源隔离方面的独特价值。

l **性能优势。**虽然DDB的性能对我们来说已经相当不错,但在某些特定场景下,由于其底层基于MySQL,因此在单行更新等方面可能会遇到一些性能瓶颈。相比之下,OceanBase在这方面进行了专项优化,表现更为出色。

l **单机分布式一体化特性,**这一特性是OceanBase 4.0版本提出的,它为云信带来了显著价值。因为并非所有业务都需部署如DDB般庞大的数据库,尤其对于发号器、配置中心等轻量级服务,单机版数据库便足以应对。OceanBase 正是满足了这一需求,其一体化架构统一了底层数据库,极大简化了运维流程,对云信而言意义非凡。

2、kv数据库-redis

大容量redis场景下,相比于使用hbase作为存储层,obkv的优势包括组件少、运维简单,以及高可用能力增强。此外选用obkv还可以帮助我们统一存储底座,对于减少运维成本还是有很有意义的。

2、kv数据库-hbase

历史消息存储这样典型的hbase使用场景下,obkv有以下优势:

l 成本优势。相比HBase1.x,压缩率显著提升,大大降低了成本。官方数据也证实了这一点。

l 高可用能力增强,这是我们尤为看重的一点。

l 接入较简单。官方提供了一个与HBase兼容的客户端SDK,接入简便,因其与HBase客户端高度相似。

l 运维部署简单。OBKV相比HBase极大的简化了部署,特别适合云信的私有化场景。

在私有化环境中,很多客户的需求并不需要大规模的部署。此时,如果采用HBase来处理历史消息,可能会显得过于庞大和复杂。

如果此时我们改用OBKV,部署将变得非常简单,能够更好地实现公有云与私有化环境的功能一致性。在私有化环境中,由于无法部署HBase,我们往往不得不割舍某些功能或采用其他方式实现,这不仅增加了开发成本,也损害了用户的体验。

采用OceanBase后,我们在私有化落地方面的挑战得到有效克服,实现了与公有云功能的一致性。OceanBase 相比 HBase 组件少、部署简单、运维方便,解决了私有化过程中的难点。

七、OceanBase与MySQL/Hbase对比实测

1、压缩

在实践中,我们曾将线上数据库同步至OceanBase与MySQL 8.0进行对比测试。测试中,云信特别关注了核心大表,尤其是至关重要且规模庞大的离线消息表。OceanBase 的出色表现再次证明了其在处理这类核心数据上的卓越能力。

以下表为例,OceanBase的压缩比高达4:1左右。相比之下,无论是页压缩还是大字段压缩,SQL 8.0的压缩比都只能达到约1.5或更低,不超过2:1。显然,OceanBase在这方面具有显著优势。高压缩比直接转化为实实在在的成本节约,对云信而言意义重大。

2、单行更新

此次单行更新测试,使用了OceanBase官方文档中的脚本。

结果显示,无论是低并发还是高并发场景,OceanBase 4.2.1版本相比MySQL 5.7和8.0都表现出明显优势。尤其在并发增加时,OceanBase的优势更为显著。这对于IM系统中需要单行更新的场景来说,将极大提升系统的稳定性。

3、kv-redis场景

对一个简单字符串场景的性能测试,主要对比了HBase、TIKV、OBKV以及原生Redis(通过obkv-4.2.5的POC版本)在get/set方法上的表现。

结果显示,OBKV相较于云信之前使用的HBase,在性能上确实有所提升。特别是在P999上的表现尤为突出。

对于复杂数据结构而言,OBKV同样展现出了优势。这得益于它针对Redis数据结构进行的优化,使得其写入能力相较于Redis-proxy+kv架构更为出色,在读取方面,目前来看各种方案各有优劣。

八、未来展望

**第一,逐步上线OceanBase。**目前,我们的测试工作正在紧锣密鼓地进行中,测试环境已搭建完毕并投入运行。会按照先部署OBKV,再使用OceanBase替换MySQL的顺序逐步灰度和上线。当前部分业务已经正式上线使用 OceanBase。

**第二,异地容灾。**由于之前数据库底座的限制,云信的容灾方案相对复杂。在OceanBase的支持下,有望简化整个容灾方案。目前,我们正对此进行深入研究。

**第三, 迁移obkv-redis。**初期,我们可能会优先上线基于现有redis-proxy+KV的方案,只是将KV从HBase更换为OBKV。我们会先运行这种方案,待其逐渐稳定后,再考虑迁移到obkv-redis。

第四, **使用OceanBase的HTAP功能。**云信不仅拥有IM系统的核心在线功能,还集成了数据统计能力。当前,我们可能因系统分割,需借助数据平台和CDC来实现数据同步与数仓分析。若OceanBase的HTAP功能符合业务需求,将极大简化整体数据架构,促进系统间的高效集成。

另外,在测试过程中,我们对OceanBase提出了许多需求,都得到了OceanBase的积极反馈。未来也对OceanBase的新特性和新功能充满期待。

相关推荐
Edingbrugh.南空1 天前
Flink OceanBase CDC 环境配置与验证
大数据·flink·oceanbase
丶意冷1 天前
mybatisPlus分页方言设置错误问题 mybatisPlus对于Oceanbase的Oracle租户分页识别错误
java·数据库·oracle·oceanbase
漫步者TZ13 天前
【StarRocks系列】建表优化
starrocks·分布式数据库
.Eyes13 天前
OBCP第二章 OceanBase 存储引擎高级技术学习笔记
笔记·学习·oceanbase
漫步者TZ14 天前
【StarRocks系列】StarRocks vs Mysql
数据库·starrocks·mysql·分布式数据库
Tapdata 钛铂数据15 天前
信创 CDC 实战|国产数据库的数据高速通道:OceanBase 实时入仓 StarRocks
数据库·oceanbase
Dnui_King21 天前
OceanBase (DBA)一面面经
数据库·oceanbase·dba
OceanBase数据库官方博客23 天前
OceanBase v4.3.5 特性解读:通过OSS WORM特性进行备份归档
oceanbase·分布式数据库·存储
OceanBase数据库官方博客23 天前
常用的OceanBase调优配置参数
oceanbase·分布式数据库·参数