万台分布式数据库的创新运营
作者简介
周小军
腾讯SNG社交网络运营中心高级运维工程师
资深运维专家,拥有十几年的IT运维经验,擅长互联网网站架构、云计算平台及运维、自动化运维开发等领域,具有十万台级规模的基础设施规划及运营能力,腾讯学院讲师。 目前在腾讯社交网络运营中心负责数据运维和接入运维工作。
前言
社交业务是典型的海量用户平台和海量并发规模的产品,从07年SNG采用MySQL、Memcache和自研C4a、08年自研TTC、10年自研CMEM,12年自研CKV等不同类型的关系数据库和NoSQL分布式数据库,都是为了解决高并发低延迟、可分布、高可用、不追求强一致性的数据场景。
发展到现在,社交业务共有近二万台数据存储设备服务于QQ、空间、相册、音乐、会员等产品,每秒的QPS峰值近1亿。其中10%的设备是关系型数据存储,90%的设备是NoSQL分布式数据存储。
采用的NoSQL分布式数据存储是腾讯内部自研的CKV和Grocery,存储介质有内存型和SSD型二种,分别适合于不同并发的业务接入。
一、架构介绍
CKV和Grocery是高性能海量KV分布式存储,业务数据分片到后端的存储机上,通过路由表实现数据寻址。存储机分主机和备机,主提供读写,备提供热备能力。集群系统主要由管理机、接入机和存储机三部分组成。
接入机负责数据的路由寻址和请求转发,存储机负责数据存储,管理机负责数据集群的中央配置管理。
通过接入机路由的变更和数据的快速搬迁能力,可以实现业务数据在集群内的无损快速扩缩容。
二、背景与挑战
社交业务的高速发展带来存储设备规模的不断扩增,在2012年数据团队所运维的存储设备已高达一万多台。这个阶段的数据团队主要的精力放在集群搭建、机器上线、业务接入、资源扩容、故障处理等日常运维,急剧扩大的存储集群运维事务消耗了运维工程师大量的日常 时间,暴露出运维工作上的几大问题。
1. 成本高
存储没有生命周期管理机制,新业务不断接入内存存储,老业务却不能及时从内存存储中下线,造成内存存储不断扩大,成本不断增加;由于长尾业务访问量下滑,造成大量的存储设备利用率极低。
分布式数据中业务分布的特点,决定了明星业务和长尾业务是混布在集群内的存储设备中,因此无法用传统设备维度的低负载方法来考核业务的合理容量。
数据存储采用一主一备热方式,主机对业务提供读写服务,备机提供容灾能力。在这种架构下不提供服务的备机负载是极低的,因此现网有数千台备机处于计算资源闲置的状态,得不到合理利用。
2、运维效率低
在效率上,业务的接入、数据表的缩容扩容都需要运维人工处理,每天有近一百多个业务表的扩缩容操作,按每个操作流程5分钟来计算,平均要消耗8个小时的运维时间。
在数据搬迁流程上效率低,数据搬迁需要人工计算目标存储机容量、需要手工发起搬迁流程、搬迁失败率高、搬迁后源表要手工清理旧数据等,操作步骤复杂,流程不闭环。
一个集群仓库具有上千台设备,几百个业务接入,各个业务的并发访问各有差异,因此,采用分布式的架构决定了集群仓库内的存储和接入机的负载不能均匀利用,出现高负载设备和低负载长期共存的不合理方式。
业务在从A集群搬迁到B集群时也不具备自动化的搬迁能力,需要业务自行从备份池导入冷备数据,人工追流水,检查数据一致性后再把业务读写切到B集群,业务介入成本过高。
3、故障对服务质量的挑战
在质量上问题也非常频繁,业务挑战很大。主备架构中的主机死机时,Master会在随后的几次检查确认后,自动把备机切换到主机,并向运维工程师发出电话告警,提醒工程师上线处理故障机器。
由于备机切到主机后变成单点,所以工程师在处理主机故障时还得手工发起数据搬迁流程,把数据搬迁到集群内的其他存储机。数据搬迁流程长达1小时,在半夜发生二三起主机死机故障时,也就意味着值班工程师一晚无眠,通宵要跟踪数据搬迁成功。
给值班工程师带来很大的痛苦,白天已经无法正常工作。高峰期一周有70多起电话告警,疲惫的工程师很容易错过另一个告警,结果屡次发生主机死机得不到及时处理,备机再次故障的双机热失效事故。
业务对内存和SSD存储的延迟和成功率要求也非常高,服务访问延迟要求在几毫秒以内,成功率要求达到3个9。主机死机后的主备切换、设备高负载、服务进程异常、网络一有堵塞或抖动等都会造成失败率瞬间飙升。模调告警的频发开发压力大,运维压力也大。
4、运维文化
在集群运维上,存储系统研发团队所提供的运维工具不是从运维角度出发,在体验、运维便利性、二次开发能力等方面做得不太好,运维使用非常痛苦。
经过持续的能力建设,我们在成本、效率、质量和团队工具文化等几个方面获得显著的进步。下面分别介绍下我们的实践和方法论。
三、成本
1. 我们的目标
1)业务数据能随着业务生命周期自动调度
业务从新接入后,存储容量是随时变化的,如果在新接入时给业务分配的存储容量过高会造成内存浪费。因此存储容量能够随着业务数据量的变化按需伸缩,保证存储容积率在一个合理的范围。
在业务进入衰退期后,访问量开始下滑,这时业务数据存储在内存中便存在浪费,应该即时将访问量不大的记录动态迁移到非内存存储介质中,保证存储介质的合理性。
2)定义数据的低负载指标
传统的按设备CPU、网络及内存等方式来计算利用率的低负载指标不适用于分布式数据存储,所以要定义一个科学的,能准确衡量业务负载的指标来衡量业务利用情况。
3)备机能提供闲置的计算资源
应能把备机闲置的计算资源共享出来,用于离线计算等对实时计算不敏感的业务。
4)业务数据透明化
把存储在内存或硬盘中的记录透明出来,通过运营数据来驱动业务存储优化。
2. 二级存储及访问密度指标
针对业务生命周期管理,我们采用二级存储架构来解决冷热数据分层。在数据分层方案上,有一种方案是内存缓存+SSD磁盘存储的架构,全量数据存储在SSD磁盘,内存只保存缓存记录,读事务落到内存缓存上,写事务直接写SSD磁盘,类似业界Memcached+MySQL的架构。
但在架构测试中发现,这种架构的缺点是后端的SSD磁盘无法支撑高并发的密集写,单机的写QPS过万后,写能力急剧下降,造成业务写延迟飚升。
目前所采用的成熟架构是,全量数据分别存储在内存和SSD磁盘上,内存存储热数据,SSD磁盘存储冷数据,热记录的读写均在内存中进行。通过LRU算法来定期淘汰冷数据。一定时间内访问有3次的记录自动迁移到内存上。
要挖掘运营数据,建立一套存储负载模型来分析业务存储数据的特性,建立包括并发读写、存储量趋势、读写延迟、成功率、业务特性等在内的监控数据,以运营数据来评估存储服务的容量和负载率。
运维根据存储机的并发读写经验值及单机存储容量,制定访问密度的负载指标,算法为业务QPS/存储容量。譬如存储机提供50GB的存储容量,最大QPS为5万,即最大的访问密度=5万/50GB = 1000次读写/GB。
在访问密度的基础上制定各层的业务接入标准,内存存储的最佳成本为每GB 600-800次读写/秒,SSD存储的最佳成本为每GB 40-50次读写/秒。
对于0-10以下访问密度的业务视为无负载或极低负载,推动业务下线。
我们通过QA协助,以数据存储的访问密度作为衡量业务合理负载的考核建议指标,让业务能更科学的使用各类介质存储。
采用二层存储自动调度架构及访问密度指标后,目前已有80%的冷记录沉降到SSD存储中,节省了上万台内存存储设备,访问密度从初期的200提升到600,提升了三倍。
3. 存储备机复用
核心思路是将备机空闲的计算资源打包成服务提供给上层逻辑业务使用,并在出现存储机主备切换的场景下能及时销毁逻辑业务,回收CPU及网卡等资源来处理存储业务请求。
主要是利用虚拟化技术将备机生产出虚拟机提供给上层业务使用,由虚拟化管理平台(CAE)负责虚拟机资源的管理,业务侧利用织云系统申请虚拟机做业务部署/扩容等操作,同时要求在主备切换场景下,CKV系统可以主动发起虚拟机销毁任务。
方案的挑战有许多:
1. 备机的旧内核不支持虚拟化平台,线上直接升级内核数据丢失风险高,最后通过数据搬迁的方式,把空闲存储机升级内核后再重新部署到集群中。
2. 受限于存储备机的内存使用率,虚拟机的内存最大只有4GB,需要选择对内存要求不高的特定业务来上线。
3. CKV主备机切换后,备机上的虚拟子机能否自动下线,并自动补充扩容虚拟上线的功能实现。
下图是存储备机的流程:
项目实施后,累计提升资源利用率的备机近千台,提升后的备机机器平均CPU负载超过50%,同时也减少了业务对一千多台虚拟子机的资源需求,达到双赢效果。
4. 内存碎片整理
为提高系统性能,不同于Redis简单的mallc/free封装,CKV将共享内存切分成固定长度的存储块。系统在启动时申请一块大共享内存,将其分割成固定长度的存储块,存储块通过下标组织成一条空闲块链。当收到添加数据的请求时,从空闲块链中不断取出空闲块存放用户数据,直到存放完成形成一条用户数据块链。
存储块默认86字节,在业务接入时按业务预估的记录平均长度来配置最适合的大小。但如果业务预估不准确,或者随着业务记录的不断增加,记录长度发生变化,就会造成存储块长度和记录长度不匹配,导致碎片率上升造成内存浪费的现象。
为优化现网内存碎片率,运维团队从现网存储进行记录采样,获取记录的长度,去除头部和尾部后,取中间80%来装箱,找出现网最优的存储块分配字节。
拿到最优长度的存储块分配大小后,工程师在目标存储设备分配存储单元,将源存储设备的数据搬迁到目标存储机器,而后将源存储设备的存储块空间释放,从而实现存储最优能力。
经过一年的碎片优化及数据搬迁,碎片率下降5%,节省了几百台存储机器。并且碎片优化任务已经成为现网的常规调度作业之一。
5. 未来计划
在未来的计划中,团队继续寻找成本优化的最佳实践,譬如接入机和存储机的同机部署;多核并行能力的深入优化;存储备机上Docker计算资源共享和调度;热冷存储和归档存储的三级存储架构等方案的探索与落地等。
四、数据运维效率
原生的NoSQL分布式数据存储提供了数据搬迁接口,可以在业务无损的情况下实现透明的数据灵活调度。但在早期运营时自动化能力水平不高,许多扩容和缩容都需要运维工程师手工分析和操作。因此,在数据搬迁接口之上,数据团队开发和封装了许多高效运维工具。
1. 自动扩缩容
首先是存储容量实现按需分配,集群有存储容量调度能力,实时监控业务容量的存储容量。当存储容量达到93%时启动自动扩容流程,当存储容量降低到70%时启动缩容流程;保证业务存储容量自动维持在85%的水位。
现在每天有100多起自动伸缩作业,不但节省了成本,还节省了大量的运维人力。
2. 高效的集群内数据搬迁能力
数据层搬迁调度项目主要为了解决数据层长期以来的仓库内数据调度效率低,速度缓慢,设备轮转效率差等问题,通过数据分析上报分析,搬迁效率提升,搬迁流程自动化等手段。
我们实现数据层接入机以及存储机的自动批量搬迁调度,包括自动部署,自动搬迁,自动下线,批量调度等功能,使得数据层摆脱传统手工十几个步骤的操作,可以做到机器快速部署,大批量腾挪,无人值守调度,设备快速回流复用。
主要的建设点是:
1)无人值守
数据搬迁调蓄全部实现了全流程无人值守。设备自动批量部署上架,录入批量下架IP列表,后台实现自动资源分配,自动数据搬迁,失败自动重试,搬迁完成后自动清理下架;
2)搬迁性能提升
搬迁进程做重构,从单进程搬迁改造为多进程并发搬迁,且支持定制化限速,将搬迁速度缩短了一倍。
3)智能判断
调度中加入角色安全性检查,负载安全性检查,优先级以及黑白名单机制,保证自动调度不会导致现网服务质量受损,整体调度流程安全可靠。
目前的搬迁能力上,搬迁效率提升了一倍,成功率从手工的50%提升到90%。几百台数据存储机二周便可完成基本自动化的数据搬迁调度。
3. 集群的负载自动调平
调度器动态和自动将不同访问密度的业务数据选择合适的机器来混布,调度算法会根据每个主机当前的物理资源情况来做优化,实现物理资源利用率最大化,并保证各个主机的流量平均分配,不会造成局部热点。
调平流程如下图:
譬如存储机的调平作业,首先获取集群内近千台存储机的性能数据,按存储单元上的并发请求进行装包计算,从高负载机的存储单元依次装包到低负载机,模拟负载计算完成后,生成数据搬迁作业,将任务发送到后台进行数据搬迁。
数据的搬迁方式有三种:
1)存储机中转对调:A机搬迁到B机,B机再搬迁到C机;
2)存储机对调:A机搬迁到B机;
3)存储打散:A机数据搬迁到B、C、D、E等多台存储机。
不同的搬迁式依照不同的场景进行采纳。
五、服务质量
在平台的三层技术架构:接入层、逻辑层和数据存储层中,前二层主要是变更所造成的服务质量较多,而更多的服务质量事件多发生在数据存储层。
数据存储层要满足逻辑层几毫秒以内3个9成功率的访问服务。只要稍有网络抖动、交换机故障、机器高负载、热KEY和主机异常都会导致业务访问失败率骤升,引发大量的模调告警。
而一台或多台存储设备上往往混布了十几个以上业务,一异常就会波及一批业务。
我们汇总的质量问题原因有:
1. 主机或备机死机:主备切换导致业务访问切换期间的异常
2. 存储机管道堵塞:写量太大导致同步进程阻塞
3. 特定内核延迟高:某个版本的内核工作一段时间后出现延迟上升
4. 热点读写:业务热点拉取Key导致存储机流量满
5. 网络质量差:上联交换机有突发流量导致端口BUFF满而丢包,或早期部署的交换机性能差
6. 进程重启后不服务:进程退出重启后无法使用共享内存
7. 接入机TCP连接数满:部分长连接业务过多创建连接导致连接数消耗光,影响到其他业务
8. 高负载:业务上量导致CPU或网络包量过载
9. 机器网卡降级:千兆网卡突降到百兆
10. 空查询:从内存存储中透传的热点空查询导致SSD存储集群毛刺
11. 各类故障等等……
各种原因的故障对现网服务的挑战很大,也给运维消耗了大量的排查人力。针对服务质量,我们从几个方法来优化服务,提升业务质量:
1. 高可用优化
1)缩短主备切换影响时长,通过把故障探测周期缩短,探测频率优化的方案,主备切换的时间优化了4倍;
2)数据自动搬迁
3)数据同步进程优化,提高安全阀值,延缓写失败
2. 性能优化
性能优化主要是系统核心引擎改造为多进程及多线程模式,多进程充分利用多核CPU的处理能力;多线程模型下让核心线程只处理读写请求,消除毛刺。
3. 故障自愈
传统运维故障解决流程是监控数据触发告警、工程师上线检查告警指标、问题定位、调用工具完成故障解决。
在监控能力、自动化工具和处理经验都积累沉淀后,我们开始实现集群的故障自愈能力。故障自愈是一个规范化的故障自动化处理服务,通过和L5、逻辑层、数据调度作业平台、配置管理中心、基础告警系统等核心或外围系统的流程打通,实现了告警发现、关联链路、告警收敛分析、自动调度故障恢复等功能。
故障自愈的实现方法流程是
1)各层的关键数据定期上报,包括L5、逻辑层、内存接入机、内存存储机、SSD接入机等的延迟和错误码上报到监控数据库。
2)故障检测任务定期检查最新的监控数据,当发现延迟率或错误码率上升时,判断是单点还是多点问题,是否收敛
3)检测任务关联相关的监控链路,譬如基础监控数据、集群死机监控等
4)判断故障点
5)启用相应的调度任务进行自愈
以下为一个典型的故障自愈场景
1)定期作业探测到某业务的监控数据有较多超时
2)检查该业务分布的接入机和存储机链路,判断超时是否有汇聚,汇聚结果显示一台存储机超时,机器的CPU负载瞬间过高;再关联该存储机上的分布业务时,判断是某业务请求量骤然增加导致CPU过载
3)对访问量最高的业务自动扩容,同时计算扩容后的设备平均负载不超过60%
4)重新检查业务超时是否恢复,如果未恢复触发人工告警,知会运维工程师上线介入处理
5)故障分析结果和处理进度等信息上报到DLP,由DLP关联分析发出告警,让业务第一时间知道存储的故障、原因及处理进度
目前自愈系统每周可以探测到几十个存储实例的异常,发起自愈次数上百次,自愈成功达到60%左右,目标是达到80%-90%的成功率。
下图是自愈调度后的微信通知:
六、DaaS服务能力
互联网产品间竞争是白热化的,落后竞争对手一个月足以失去市场领先地位。开发必须以月甚至以周来抢速度、抢版本。因此产品研发和发布需要有强健的研发机制保证,让产品开发更加敏捷和快速。
如果从零开始叠加产品,如果没有积累良久的基础架构,团队中代码、数据库、架构等都要从头开始,足以浪费大量的时间成本。平台的基础设施建设非常重要,可以大幅度降低产品创业的成本和负担,让团队把更多精力集中到最核心的创新上来。
我们已经基本实现了数据即服务的平台化能力,实现了存储资源的生命周期管理,业务从接入、按需分配、自动下沉、业务隔离、故障自愈等都可以高效和自助完成。
在服务化实践过程中,数据团队也把自己的开发能力从脚本、工具和向调度化迈进,最终实现一个具备监控、数据分析、调度化的智能存储运维平台,促进集群内数据高效流动,高效利用海量数据资源。
数据即服务解放了研发团队的精力,研发团队创建产品时,只需要接入一个数据库实例就可以完成产品的开发、测试及上线部署。后端的数据库扩展、故障容错、质量监控、容量管理等不需要关心,业务完全是自助服务。
未来数据规模成倍增长时,团队人数不需要增加。我们不断借鉴IaaS、PaaS等优秀资源管理平台的架构和经验,驱动团队树立更高的目标,用创新的手段和工程化能力来实践落地。
目前,我们已经把服务能力输出到腾讯云的产品上,如CRS(Cloud Redis Store),为第三方用户提供更优质的数据存储服务。
欢迎加入本站公开兴趣群
软件开发技术群
兴趣范围包括:Java,C/C++,Python,PHP,Ruby,shell等各种语言开发经验交流,各种框架使用,外包项目机会,学习、培训、跳槽等交流
QQ群:26931708
Hadoop源代码研究群
兴趣范围包括:Hadoop源代码解读,改进,优化,分布式系统场景定制,与Hadoop有关的各种开源项目,总之就是玩转Hadoop
QQ群:288410967