《APACHE HIVE 社区交流群》里有贝壳等公司的朋友希望分享一下元数据服务MetaStore修改Mysql字符集的问题,近期抽空简单总结了一下,分享给大家。
1 背景
先简单介绍一下我们嘀嘀元数据曾经遇到的痛点:单点mysql;单表数据量3亿+ 。因此,我们迫切需要做分库分表,并将mysql交由专业的DBA运维,让专业的人做专业的事。然后,我们便开始了mysql迁移之旅。
2 难点及方案
我们基于Waggle-dance做了MS的Federation,解决了单点mysql压力大的问题,近期我们计划将MS的Federation方案贡献给社区,大家有兴趣的可以关注一下。
对于单表数据量过大的问题,我们将Mysql迁移至我们的服务平台,交由专业的DBA进行维护,后续做分库分表来解决。
在我们迁移Mysql的过程中,其中有一项工作主要由我负责:便是将latin修改为utf-8字符集。可能有朋友会说,这有什么难点?我们元数据服务MS服务全嘀嘀数仓大数据体系,因此,我们要做到对用户完全透明。
首先是修改字符集的可行性。我们摸排了当前mysql中存储的元数据信息,充分评估了修改字符集可能带来的影响。经过反复测试验证,最终认为可以修改字符集latin为utf-8.
熟悉mysql的朋友都知道,alter table操作会锁表,而锁表的时间和表的大小正相关,我们测试发现,对于大表通过alter修改字符集,会锁表长达10+分钟,这对线上生产来说是不可忍受的。我们最终调研到Percona Toolkit
, 通过pt-online-schema-change
来透明修改字符集。
percona-toolkit的安装:
1 | 安装命令: |
有pt-online-schema-change
就够了吗?
不,远远不够。它的原理大致是这样:对于 A表(字符集是latin),新建一个A‘ 表(字符集utf-8),然后A‘从A里同步数据,数据同步完成之后,锁表,然后进行rename操作,将A’表修改为A表。
这里最大的痛点,便是在同步完成数据之后,renama的瞬间,可能存在A表不存在的情况(当然该问题在高版本的Mysql中已经修复)。为此,我们调研到pt-online-schema-change
还有插件扩展功能。通过插件,我们可以在rename前和rename之后做一些事情。
2.1 方案
实现方案:
- 1,在rename之前,我们会设置一个rename标签信号,然后休眠数秒(假如是5秒,该时间取决于慢查询的平均时长);
- 2,我们在MS侧增添一个哨兵,当哨兵监测到rename标签信号时,将所有请求MS的thrift请求夯住等待;
- 3,在rename之后(rename动作通常是秒级完成),取消rename标签信号。
- 4,MS哨兵监测到rename标签消失,放开所有夯住的请求,服务恢复。
2.2 MS哨兵实现
在MS中,实现一个哨兵角色,然后轮巡检测是否有rename标签信号;在thrift层面,如果哨兵监测到rename操作,便夯住请求,进行等待。
1 | public class HiveUtil { |
这里需要跟大家分享的一点便是,哨兵角色通过异步线程来实现,从而达到和thrift请求处理的相互隔离。而thrift请求夯住的实现是在org.apache.hadoop.hive.metastore.TUGIBasedProcessor#process
中做的。
1 | public boolean process(final TProtocol in, final TProtocol out) throws TException { |
为保障最大程度的透明,我们还增加了MS客户端连接失败的重试次数;beeline端的连接失败重试次数。
3 实践
我们针对实际表的现状,将字符集修改分为大表和小表两类。因为小表的alter操作,锁表时间很短,无需做特别复杂的流程。下面主要介绍下大表的升级过程。
3.1 备份与前期准备
首先大的升级前,我们做好数据备份。dump一份mysql数据。
另外,我们还生成了一份升级前的元数据文件,用于升级前后的比对,以确保升级成功。
1 | -- 升级后的表结构比对文件 |
3.2 修改索引
这里有一个坑:我们测试环境发现升级过程中有异常:Specified key was too long; max key length is 3072 bytes
所以,修改字符集前,需要先重建如下索引:
1 | 重建前缀索引,规避异常:Specified key was too long; max key length is 3072 bytes |
3.3 修改大表字符集
我们对pt工具封装了下,详见附。
修改命令,以PARTITION_KEYS
表的修改为例:
1 | sh pt-toolkit.sh PARTITION_KEYS " default character set utf8 collate utf8_general_ci \ |
3.4 升级后的校验
采用3.1的命令,生成一份升级后的比对文件,然后对升级前后进行对比,若所有的latin都修改为utf-8,则升级成功。
3.5 回滚方案
在升级过程中,出现异常,采用逆向操作,将字符集恢复为latin即可。这里不再赘述。
4 总结
大量的压测论证给了我们足够的信心,成功完成升级变更,全程用户无感知完全透明。尤其是MS服务请求夯住的实现,为我们今后不停服的透明升级提供了新的思路。
欢迎在MS元数据服务有类似痛点的朋友,一起交流。
5 附
pt-toolkit.sh
1 | !/bin/bash |
插件 pt-tools.pl
1 | package pt_online_schema_change_plugin; |
本文链接: https://stefanxiepj.github.io/archives/599c076e.html
版权声明: 本作品采用 知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议 进行许可。转载请注明出处!