作者:杨尚刚,微博数据库技术负责人
编者按: 作为中国最具影响力的社交媒体平台之一,微博(旧称新浪微博,股票代码:09898)自2009年上线以来已发展成为集内容发布、社交互动、热点传播于一体的综合性社交网络。据公开数据显示,2024年微博月活跃用户规模突破5.83亿。
面对庞大的用户体量和日益复杂的业务场景,微博数据库平台面临关键挑战:如何在保障海量数据处理能力的同时,实现系统稳定性与成本效益的平衡。经过严谨的技术评估,团队最终完成了核心数据库系统的战略升级。在本文中,微博数据库技术负责人杨尚刚将从技术选型、方案设计到落地实践等维度,深度解析这场关乎亿级用户体验的数据库进化之路。
微博数据库平台架构及现状
微博的数据库平台主要分为三部分:常见的主流关系型数据库、 NoSQL 数据库托管,完整的 OLTP 和 OLAP 解决方案支撑,推动公司数据库技术创新实践和落地。
其中,数据库实例规模总计数万个,NoSQL 数据库以 Redis 为主,每天的访问量在万亿级别,十亿级访问峰值。自2011年开始,我们大量使用 Redis ,并基于 Redis 研发了多个内部分支,持久化存储数据规模达 PB 级。
下图为微博的数据库架构图:资源层包含早期的自建物理机、私有云和用于解决资源弹性扩缩容问题的公有云;调度层负责资源的管理和调度,包括内部自研的资源调度平台和开源的 Kubernetes;服务层主要是关系型数据库,包含MySQL、PostgreSQL、ClickHouse、Milvus、OceanBase、 MongoDB 等。当前产品种类繁多、导致平台管理成本比较高,稳定性和易用性也存在问题。
由于近几年经济状况较差,人力成本越来越高,而业务的正常发展、存储资源的持续增长,以及架构升级,都需要更多的人力支撑,因此,为降本增效,我们需要更加简单高效、低成本的技术架构。
架构升级,优先解决MySQL痛点
在成本控制和精细化风险把控的背景下,需要用有限的服务器资源支撑业务的平稳增长,并实现资源利用最大化和高效交付。 在关系型数据库的应用中,MySQL使用范围较广,且存在的问题较为突出,所以在此次架构升级中,我们优先解决MySQL的应用痛点,比如:
- 长尾数据多。像微博评论这样的数据每天都在大规模增长,且需要长期保存,导致长尾数据非常多,占用存储空间。
- 分库分表的不可持续性。当数据库实例所需规格超过机器规格就需要扩容,通常我们只能考虑分库分表方案,短暂满足了业务要求,但带来了更高的管理成本和业务成本。
- 高可用数据安全问题。 MySQL主要通过异步复制来同步数据,虽然也支持半同步,但会带来一定的性能损耗。MySQL 5.7 支持的 MGR 集群方案相对完善,运维成本却相对高。当进行主从切换后,存在数据一致性的风险。
- 存储成本高。 MySQL 部署主要是一主两从架构,相当于双重备份。如下图所示,从2013年到2020年,机械盘和 SSD 盘的成本越来越接近,机械盘在存储成本的优势没有太大变化。
针对 MySQL 的痛点问题,我们计划从如下几个方面进行优化。
1.优化存储成本,不同场景使用不用存储模式。
2016年,为了解决延迟和性能问题,我们把数据从机械硬盘迁移到 QLC SSD。然而,随着业务场景的变化,QLC SSD 的成本优势并不明显,某些情况下使用机械硬盘可能是一个更优的选择,但在某些场景下,使用 QLC SSD 成本仅能降低约10%~20%,相比之下,机械硬盘由于其较高的单机存储密度,成本降低幅度可能更大,因此需要针对不同的业务场景使用不同的存储模式。
2.长尾数据归档到 S3。
我们计划将长尾数据归档到 S3,且正在调研适合的方案。已知MariaDB 插件支持 S3 存储,其本质是通过底层 S3 实现数据同步,而非传统意义上的集群数据同步。这种方案可显著降低存储成本,甚至可能低于使用硬盘的成本。但需要注意的是,该方案对业务场景有一定要求,例如对于数据更新频繁的表,可能会受到限制,更适合存储很少更新或基本不更新的数据。此外,OceanBase 也支持 S3 方案,其方案可行性正在调研中。
3.通过压缩软件、硬件降低成本。
软件压缩和硬件压缩技术也是我们整体测试的方面。MySQL 从5.5版本开始支持压缩,到5.7和8.0版本引入了新的压缩方式。不过MySQL自带的 压缩的性能损耗较大,例如使用 MySQL 压缩可以节省约40%的存储空间,但性能可能会下降约66%。由于我们了解到OceanBase具备较强的降本能力,因此,我们后续考虑通过OceanBase来降低硬件成本与存储成本,同时减少性能损耗。
4.资源池化以实现弹性扩展。
资源池化是解决弹性扩展能力的重要方向,但其实现需要较强的研发实力。我们暂不具备实施资源池化的条件,但可以参考业界的先进方案,如 AWS 或 PolarDB,再或者引入OceanBase时利用其资源池化能力。资源池化的主要目标是解决 MySQL 扩展困难的问题,尤其是数据存储和扩容的难点。
通过多方面的优化措施,我们希望能够有效解决 MySQL 的痛点问题,提升系统性能和成本效益。而在调研数据库方案时,发现OceanBase比较符合我们的预期,便在业务中进行尝试。
分区表替代分库分表,又稳又省
OceanBase 是一款完全自主研发的原生分布式数据库,支持平滑扩展与弹性扩缩容、高度兼容 MySQL,能够平滑、快速、小成本搬迁应用与数据,且具备高可用(RPO=0,RTO小于8s)能力,还有非常活跃的开源社区,因此我们开始尝试在某些场景引入 OceanBase。
举个例子,某个系统此前面临分库分表拆分复杂、数据不一致、多实例导致的机器资源浪费、运维成本高等问题。我们尝试将该系统的数据库替换为 OceanBase,前期测试和部署过程都比较顺利,解决了该系统使用 MySQL 时问题。
采用 OceanBase 后,主要收益如下:
- 我们摒弃了原有的 MySQL 分库分表策略,转而使用 OceanBase 分区表。从业务层面来看,相当于一张大表,从而简化了业务读写逻辑,完全解决了数据一致性问题。
- OceanBase 底层存储使用通用压缩和数据编码压缩,数据压缩比高于 MySQL,且性能不受影响。在系统迁移到 OceanBase 后,存储占用从 50TB 下降到 27TB,成本节省46%。
- 系统已稳定运行半年多,证明了 OceanBase 的强稳定性。
- OceanBase 分布式数据库天然具备高可用能力,集群部署完成后,不需要额外花大量工作维护数据的多副本,少数节点出现故障不影响业务使用;无需像 MySQL 那样引入额外的组件来保证集群切换,进一步降低了运维复杂性和 DBA 运维成本。
选对技术策略,降本增效
在引入 OceanBase 的过程中,我们收获了很多实践经验,供大家做参考。
实践1:分区表设计
分区表是数据库设计中常见的优化手段,尤其在处理大规模数据时。对于MySQL用户来说,分区表的设计和使用已有诸多规范、文档供阅读。然而,MySQL早期版本的分区表存在一些问题,因此在实际应用中,通常建议使用分表而非分区表。MySQL 单表通常为N千万行,大于此数量需要分库分表。
OceanBase 分区表设计理念与 MySQL 有显著区别,主要通过分区表设计来实现大规模数据的高效管理,不存在单表数据量上限,对于大数据量表建议使用分区表,且单个分区表可以控制在100GB以下(对应MySQL 600GB~800GB)。同时,分区数量建议在服务器台数的2-3倍,以及 CPU逻辑核数的2倍范围之间,以确保数据分布均衡,避免因分区过少导致的数据不均衡问题。
OceanBase支持一级分区和二级分区。一级分区是常见的分区方式,包括 HASH、KEY、LIST、RANGE、RANGE COLOMNS、LISTCOLOMNS 等常用的分区类型,具体选择需根据业务场景和数据特点确定。例如,如果数据具有时间维度特征,范围分区可能更为合适;如果数据需要根据特定值进行分区,列表分区可能是更好的选择。
二级分区相当于在一级分区的基础上,又从第二个维度进行了拆分。如果在设计初期选择了一级分区,后续需要扩展分区,直接修改分区键可能较为困难,此时可以通过引入二级分区来解决这一问题。二级分区的设计需要谨慎考虑,以确保分区的合理性和扩展性。
创建分区的目的是在特定的SQL操作中减少数据读写的总量,以减少响应时间,同时提升了可扩展性能力、可管理性、提高性能等能力。
分区表设计的主要目的是优化数据量和响应时间,降低系统负担。通过合理分区,可以有效控制并发度,确保数据规模和性能的平衡。在设计分区表时,还需要注意以下几点。
- 分区键选择。分区键应根据业务形态(热点数据打散、历史数据维护便利性、业务SQL的条件形态、分区裁剪)谨慎选择,尽量将数据均匀分布,避免数据热点问题。
- 分区类型选择。根据业务需求选择合适的分区类型,如哈希分区、范围分区或列表分区。
- 分区键与主键的关系。在 OceanBase 中,分区键必须是主键的子集,即主键中必须包含分区键。
- Range分区。考虑是否使用maxvalue,如果使用了maxvalue,后续会没办法再添加分区。
- 写放大问题。为了避免写入放大问题,选择表的自定义主键时,不要使用随机生成的值,尽量有序,比如时序递增等。
- 考虑分区裁剪优化。 分区表设计是数据库优化的重要环节,尤其在处理大规模数据时。OceanBase 的分区表设计比较灵活性,在实际应用中,需要根据业务需求和数据特点选择合适的分区策略,优化系统性能和数据管理效率。
实践2:统计信息收集
统计信息收集是数据库 SQL 优化的重要组成部分,尤其是在处理慢查询时比较依赖统计信息。无论是MySQL 还是 OceanBase,其查询优化器的执行路径都依赖于统计信息的准确性。当表的数量较多时,统计信息的收集成本较高,耗时也较长。统计信息中,直方图是较为重要的一部分,直方图收集涉及复杂的计算,带来额外成本的耗时。大分区表默认收集二级分区、一级分区、全表的统计信息和直方图,代价为:3 * {cost(全表扫)+cost(直方图)}。
统计信息收集需要注意五个方面。
其一,设置合适的默认收集并行度。
- 统计信息收集的并发度需要控制,因为其对机器性能有一定影响。建议在业务低峰期(如凌晨)进行收集,以减少对业务的影响。
- 建议并行度控制 8 个以内,业务可控的情况下,可以调大并发通过牺牲资源保证了统计信息的收集效率
- 业务租户执行:
- SQL>call dbms_stats.set_table_prefs('database_name', 'table_name', 'degree', '8’);
复制代码 其二,配置采样比例。
配置块采样,可以通过块采样的方式减少统计信息收集时要处理的数据量,也达到到快速收集的效果。但会牺牲一定的统计信息的准确性。可使用如下方式设置。
配置开启块采样:- SQL>call dbms_stats.set_table_prefs('databse_name','table_name','block_sample','True');
复制代码 配置采样比例,可根据表的数量级进行配置,通常情况下,采集千万级的数据即可充分反应一个表的数据特征:- SQL> call dbms_stats.set_table_prefs('databse_name','table_name','estimate_percent','0.1');
复制代码 其三,设置默认列的直方图收集方式,考虑给数据分布均匀的列设置不收集直方图。
如果该表所有列的数据分布都是均匀的,可以使用如下方式设置所有列都不收集直方图- SQL>call dbms_stats.set_table_prefs('database_name', 'table_name', 'method_opt', 'for all columns size 1');
复制代码 如果该表仅极少数列数据分布不均匀,需要收集直方图,其他列都不需要,则可以使用如下方式设置(c1,c2收集直方图,c3不收集直方图):- SQL>call dbms_stats.set_table_prefs('database_name', 'table_name', 'method_opt', 'for columns c1 size 254, c2 size 254, c3 size 1);
复制代码 跳过大对象字段,如果列中保存的都是大对象,可能会导致收集特别慢,因此,收集除大对象外的所有列:- SQL>call dbms_stats.set_table_prefs('databse_name','table_name','method_opt','for columns col1,col2,col3,... size auto');
复制代码 其四,不同场景收集统计信息的方式。
慎用设置大表采样的方式收集统计信息,设置大表采样收集时,直方图的样本数量也会变得很大,存在适得其反的效果,设置采样的方式收集统计信息仅适合只收集基础统计信息,不收集直方图的场景。业务租户执行如下。 设置所有列都不收集直方图:- call dbms_stats.set_table_prefs('database_name', 'table_name', 'method_opt', 'for all columns size 1');
复制代码 设置采样比例为10%:- call dbms_stats.set_table_prefs('database_name', 'table_name', 'estimate_percent', '10');
复制代码 其五,锁定统计信息。
考虑能否手动收集大表统计信息后,锁定相关的统计信息。需要注意的是当表的统计信息锁定后,自动收集将不会更新,适用于一些对数据特征变化不太大、数据值不敏感的场景,如果需要重新收集锁定的统计信息,需要先将其解锁。
锁定表的统计信息:- call dbms_stats.lock_table_stats('database_name', 'table_name');
复制代码 解锁表的统计信息:- call dbms_stats.unlock_table_stats('database_name', 'table_name');
复制代码 统计信息收集需要综合考虑并发度、采样比例、收集方式以及表的使用场景等因素,以确保优化器能够基于准确的统计信息生成高效的查询计划,同时避免对系统性能造成过大影响。
在KV场景、向量场景进一步探索OceanBase
由于 OceanBase 在已上线的业务中表现优秀,因此,我们计划在其他业务场景中继续进行尝试和探索。目前,我们的业务数据量较大,但读写量相对较低。未来,我们将尝试应用于读写量更大、对耗时更为敏感的业务场景,以进一步验证 OceanBase 的性能和适用性。
场景1:KV 存储优化
除了 TP 场景,微博内部的 KV 场景也面临一些挑战。以 Pika 为例,目前存在4个问题。
- 混部影响 Pika 稳定性:Pika 与 MySQL 混布,且 Pika 实例较多。如果调度不均衡,可能导致单机 Pika 实例过多,进而影响其稳定性,尤其是在遇到热点数据或机器负载不均衡时。
- 长尾数据:与 MySQL 类似,Pika 作为基于磁盘的 KV 存储,部分 Pika 实例存在长尾数据问题。这些数据需要长期存储,但又不能清理,给存储管理带来较大压力。
- 扩展性问题:Pika 本质上是单机数据库,其数据规模和扩展性面临挑战,与 MySQL 类似,单机扩展性是当前较为棘手的问题之一。
- 成本优化:成本主要分为两部分,一是 Redis 迁移到 Pika 等的迁移成本,二是引入新的平台 ARM 平台带来的成本。
优化措施分为以下两个维度。一是优化扩展性优化, 针对 Pika 的扩展性问题,我们调研了相关方案,目前考虑通过 Proxy + Pika 的方式进行管理;二是适配ARM 架构, 我们已对 Pika、Redis 服务及 Memcached 进行了 ARM 架构适配。从测试结果来看,ARM 架构在单实例性能上较同配置的x86架构有显著提升,且成本更低。但适配过程存在一定成本,尤其是在ARM架构上,编译指令和JCC(Just-In-Time Compiler)支持等方面与 x86 架构有所不同。此外,MySQL 后续也可能进行 ARM 架构适配,但其适配难度可能较 Redis 更大,因为MySQL 代码复杂度更高。
场景2:向量数据库痛点
近年来,向量数据库发展迅速,种类繁多,如主流的 Milvus、Redis、Elasticsearch、PG Vector、OceanBase 等,均支持向量索引和标量索引,功能较为全面。 目前,微博线上主要使用 Milvus 和 Elasticsearch,但使用成本、存储成本、学习成本,以及管理复杂度都比较高,在处理高维向量数据时也存在性能和扩展的瓶颈。 基于微博向量数据库的应用现状,我们将评估当前技术架构、细化业务应用场景,并探索OceanBase 向量能力在内部业务场景的落地应用。
首先,细化业务应用场景。未来,线上业务可能会继续沿用目前的多种数据库,包括 MySQL、Elasticsearch 、 OceanBase 等,我们将根据业务场景和数据规模进行细化选型,以优化成本和性能。
其次,评估磁盘索引升级 Milvus 版本持续升级与优化。对于当前使用的向量数据库,需继续升级以解决其成本和性能问题。
最后,测试 OceanBase 向量功能。 OceanBase在向量数据库方面具有一定优势,表现在:
- 索引种类丰富。支持向量索引、标量索引、半结构化索引(多值索引、空间索引)、全文索引等。
- 应用集成丰富。采用 SQL 访问,复用 MySQL 生态各个语言的客户端;提供 Python API、提供SDK, 类似Milvus SDK。
- 索引创建语法丰富。索引类型包括HNSW、IVFFlat、DiskANN(on processing);距离算法包括L2、IP、COSINE、Jaccard( on processing)。
- 向量查询丰富。支持 TOP N 排序的相似度计算;支持向量和标量混合查询;
- 部署运维方便。功能集成在数据库内核中,可以使用和 OceanBase 社区版相同的部署、运维、监控、数据迁移工具。
随着 AI 技术的发展,数据库将与 AI 结合更加深入,尤其是自然语言和SQL的结合如SQL 改写方向。同时,AI Agent 也将成为我们在 OceanBase 向量能力的探索方向,例如数据库助手、知识库等。希望利用 AI 提高内部人员的工作便捷性,降低运维复杂度,提高工作效率。
其他场景
除KV场景和向量场景计划探索OceanBase外,我们在OceanBase应用过程中还将执行以下5个计划。
1. OCP平台和自建运维管理平台融合。
我们将推进OCP平台与自建运营管理平台的整合。如果要大规模使用OceanBase,必须将其与现有的数据库管理平台进行有效整合,从而降低使用成本并提高管理效率。
2. 资源隔离。
目前,我们的资源调度方式包括Kubernetes(K8s)和自研调度系统,在实现CPU和内存资源隔离方面存在一定的局限性。OceanBase的多租户架构可以更好地实现资源隔离。
3. 数据迁移自动化。
数据迁移是将MySQL或其他数据库迁移到OceanBase的关键环节。目前,数据迁移和校验工作尚未完全自动化,仍需逐步完善。我们将致力于提高数据迁移的自动化程度,确保迁移过程的高效性和数据的准确性。
4. 集群性能调优。
随着OceanBase在微博的应用范围扩大,集群规模也越来越大,性能调优将成为一项持续性的工作。我们将根据实际使用情况,逐步积累经验,优化集群性能,以满足业务需求。
5. 多可用区容灾。
容灾能力是后续需要重点建设的领域。随着云服务和自建虚拟化环境的普及,MySQL或其他数据库的部署规模和密度不断增加,对容灾和大规模故障处理能力的需求也日益迫切。未来,我们计划将OceanBase集群部署在多个数据中心,以提高容灾能力。虽然这种部署方式可能会因网络问题对性能产生一定影响,但我们将逐步评估和优化,以确保系统的高可用性和稳定性。
总结
经过本次数据库架构的成功升级,我们持续探索更优的架构和更便捷的开发、运维方式。OceanBase 作为一款日益流行的数据库产品,在微博的应用场景中具有广阔前景,我们将积极探索更多降本增效策略,以应对未来挑战。在此过程中,我们将坚持两个原则:
- One size does not fit all。对于互联网企业而言,数据库选型至关重要,需综合考虑技术稳定性、人员技能、运营体系和业务场景等因素。
- 适合自己的才是最好的。我们将保持开放思维,持续关注 OceanBase 的发展,争取应用更多和我们业务场景适配的产品能力,助力业务发展。
最后为大家推荐这个 OceanBase 开源负责人老纪的公众号「老纪的技术唠嗑局」,会持续更新和 #数据库、#AI、#技术架构 相关的各种技术内容。欢迎感兴趣的朋友们关注!
「老纪的技术唠嗑局」不仅希望能持续给大家带来有价值的技术分享,也希望能和大家一起为开源社区贡献一份力量。如果你对 OceanBase 开源社区认可,点亮一颗小星星✨吧!你的每一个Star,都是我们努力的动力。
来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作! |