背景
一年一度的双11大促又到了,每个使用OceanBase的电商客户都在积极备战,今天我简单介绍针对一次大促活动,在OB数据库层面如何进行保障以及常见的应急预案供大家参考。
业务目标
每次大促活动前,业务层面一般都会设定一个目标保障值,类似于峰值订单量、全天订单总量等。这个是业务层面的一个指标,DBA需要根据实际的场景,将这个指标分解,得到每个数据库集群/租户对应的TPS和QPS,然后再根据这个值,去评估数据库系统容量。
资源评估
拿到了每个数据库集群/租户峰值指标后,我们接下来就要评估系统容量。由于不同业务场景不同,资源评估很难非常精细化的准确评估,通常可以按照日常的基线峰值水位,再按照当前数据库的峰值安全水位(安全CPU水位80%),对比评估出需要的机器数量。例如目前日常水位qps+tps=10000,CPU水位50%,如果大促目标为qps+tps=20000tps,那么这个时候就需要进行相应的扩容。
使用OB公有云的客户,大促能够享受到的最明显的红利之一就是阿里云机房的弹性资源,我们可以在大促期间将应用、数据库快速扩容弹出,大促后再在很短时间内弹回,实现快上快下,资源有效利用。但如果是采用私有云部署OB的模式,资源方面就需要提前做一些储备或采购,机型和日常使用的机型最好保持一致,每个机房/机柜都留一定buffer作为应急备用。
数据库扩容
上面谈到的是机器资源的采购和评估,那么在数据库本身的弹性扩容的执行操作上,无论是公有云的扩容,还是私有部署的弹性扩容,他们真正依赖的能力内核其实是一样的,都是在利用OB原生的水平扩展的能力。正式因为有了这个能力,我们才能在各种场景下对数据库执行快速的、且业务无感知的扩容。OceanBase 扩容主要包含以下3个步骤:
1、机器扩容:每个Zone等比例扩容相应OBSERVER机器。
2、负载均衡:在线迁移租户UNIT。
3、租户扩容:增加大促相关租户资源(cpu|memory)。
上述操作都可以在OCP非常方便的完成。尤其值得一提的是,OB的数据扩容迁移能力速度非常快,速度的上限由节点的网卡以及磁盘ssd速率决定。而且可以根据需要灵活调控流控。节点迁移同时不影响paxos投票,可以理解为近似物理复制,数据迁移本身的一致性校验也是ob内核内建的,100%保证一致性和完整性。dba无需值守,无需人工干预。
业务联调压测
数据库弹性扩容完成后,应用在大促前一般会进行多轮的线上压测,确保业务达标。这个过程中DBA同学需要全程关注DB业务表现以及数据库的水位,确保扩容后的容量可以支撑。另外DBA还需要做好sql审核工作,确保大促时关键链路的SQL执行都是符合预期的。
预案执行&巡检
压测达标后,到了大促前的一段时间,DBA/数据库团队同学需要联合业务开发同学,对业务系统中可以降级运行或者限流的应用、子系统进行梳理和演练。防止突发情况下,旁路业务影响主链路业务。
数据库层面也要准备好对应的预案,提前执行。包括但不限于:
- 错峰、提前执行OB数据合并
- 慢SQL巡检梳理,限流预案准备
- 旁路、数仓跑批业务降级预案
- 备份恢复降级
- 关闭OB sql_audit审核模块
- OB系统日志限流
- OCP告警项巡检
盯盘保障&应急机制
大促过程中,重点关注峰值前后数据库的各项指标。比如sql的响应时间,DB连接数,应用关于连接数/rt的报错,数据库本身CPU、转储水位等等。如果发现问题相关同学需要第一时间处理,执行降级、限流等预案。
得益于OB内核具备的限流和执行计划干预能力,DBA也能够在极端情况下对问题sql请求进行流控甚至熔断操作,而对于不符合预期的慢SQL执行计划,还可以在线修改outline,使sql按照人预期的正确计划执行,解除危机。
常见异常场景及处理机制
1、合并异常处理预案
合并发生合并异常,未在预期结束时间内完成合并,需根据以下方式进行处理:
a) 黑屏登录目标集群执行sql:
SELECT zone, svr_ip, major_version, macro_block_count, use_old_macro_block_count, merge_start_time, merge_finish_time, merge_process, ( merge_finish_time - merge_start_time ) AS cost_time, ( macro_block_count - use_old_macro_block_count ) AS merge_macro_block_count, ( macro_block_count - use_old_macro_block_count ) / ( merge_finish_time - merge_start_time ) AS avg_per_sec FROM __all_virtual_partition_sstable_image_info ORDER BY zone,svr_ip,major_version;
b) 根据sql返回定位卡合并server
c) 执行alter system stop server "xxxxx:2882";切走故障server上流量
d) kill -9 session_id ,杀掉故障server上observer进程
e) cd /home/admin/oceanbase; ulimit -s 10240; ulimit -c unlimited; /home/admin/oceanbase/bin/observer 拉起observer进程
f) 等待server状态(查询__all_server表status字段确认)为active后,再次查询步骤a) sql,查看目标server的use_old_macro_block_count字段是否在增长,如15分钟内仍无变化,联系产研进行定位
e) 待合并正常且目标server开始提供服务(查询__all_server表start_service_time字段确认)后,执行alter system start server "xxxxx:2882";
2、性能抖动预案
a) 资源内存/CPU进展
OB集群预留一部分资源做应急buffer使用,在CPU、内存出现紧张的情况下,按业务优先级进行配置调整
内存紧急释放可通过增加转储,手工发起转储操作进行应对:
alter system set minor_freeze_times=xx;
alter system minor freeze;
(alter system minor freeze tenant=('tt1') server=('xxx.xxx.xxx.xxx:2882') zone='xxx';对应对租户、server、zone发起转储)
临时关闭ocp topsql采集功能,释放ocp占用资源。
b) plan绑定
如抖动原因为大促当天烂sql流量异常导致,需进行执行计划绑定outline对烂sql进行限流:
使用sqlid创建outline
CREATE OUTLINE outline_name ON sql_id USING HINT hint_text;
例如:CREATE OUTLINE otl_name ON "xxxxx" USING HINT /*+index(table_name idx_name)*/ ;
通过查看 gv$outline 中的表,确认是否成功创建对应的 outline 名称的 OUTLINE
select * from oceanbase.gv$outline where outline_name = 'otl_name'\G;
确定新的 SQL 执行是否通过绑定的 outline 生成了新计划,当绑定 OUTLINE 的 SQL 有新的流量查询后,查询 gv$plan_cache_plan_stat 表中该 SQL 对应的计划信息中 outline_id,如果 outline_id 是在 gv$outline中查到的 outline_id 则表示该计划是按绑定的 outline 生成的执行计划,否则不是.
select sql_id, plan_id, statement, outline_id, outline_data from oceanbase.gv$plan_cache_plan_stat where statement like '%SELECT * FROM table_name WHERE xxxx =%'\G
c) 合并时抖动
如确认抖动原因是合并引起,可采取以下方式进行应急控制:
降低合并线程:alter system set merge_thread_count = 1;
降低合并使用io带宽 :alter system sys_bkgd_io_low_percentage = 10; alter system sys_bkgd_io_high_percentage = 20;
暂停合并 :alter system suspend merge(zone='xxx');
d) 连接数引发抖动
如确认抖动原因为observer上连接达到上限,且业务方应用无法主动释放连接,可采取以下方式尝试解决:
切主,确认租户leader在具体某个zone上时可采用 stop server或kill 目标server上ob进程
按用户进行分组查看连接数:select user,svr_ip,count(*) from __all_virtual_processlist where tenant='xxxx'' group by user,svr_ip order by 3 desc;
按用户,租户分组查看连接数:select user,tenant,count(*) from __all_virtual_processlist group by user,tenant order by 3 desc;
按用户,客户端IP分组查看连接数:select user,user_client_ip,count(*) from __all_virtual_processlist where tenant='xxxx' group by user,user_client_ip order by 3 desc limit 30;
按用户,状态分组查看连接数:select user,state,count(*) from __all_virtual_processlist group by user,state order by 3 desc;
e) 高压导致无主引发抖动
如发现抖动时出现大量切主,且定位切主原因为partition无主,可采取以下方式尝试解决:联系应用方进行压力控制,必要时可限流,如应用方无限流措施可参考plan绑定方式进行限流;