分布式DB规划要点

1,划分核心非核心功能,例如游戏的接入业务中,登录注册校验为核心功能,msg和日志为非核心功能,DB,server和cache都需要物理隔离,只要核心非核心存在共享资源,如DB公用1个,要是非核心出现大量整表查询,核心功能会受到影响,核心和非核心之间采用接口访问。

2,一张大表拆分到不同DB,来提升数据库性能。DB分为4个分库,模值为1024,每个分库占据256个位置,hash (test1234) = 3109729401 % 1024 = 537 在分库3.扩容方式:原分库分割为2个,每个分库占据128个位置。

3,针对hbase存储log收集系统。log表存储日志记录,meta表存储索引元数据(包含动态索引index表的名称),动态index表:存索引的具体信息,一个索引对应1张表。log列族:tag存储日志taf(如tag_LEVEL,tag_TIME,tag_HOST),message存储日志信息。meta表列族:index作用含2个,qualifile,name和span,那么存索引名称,span是索引使用的时间间隔。动态索引表:rowkey是json格式的indexRowkey字符串,如["tags":["INFO"],time: 2342343]。获取日志产生的时间,然后内部存储1个tag是的循环,匹配则为其建索引,往索引表插入1条数据。

4,定制360Altas,会做sql分组,数据库分组,哪些SQL到哪些DB。单独服务拆分成小系统,对DB每个月做DB容量的review,分析哪些表是大表,读写的QPS和容量。

5,支付则需要强事务DB,很多社交平台需要高可用,有的则关心几天的数据,有的频繁access历史数据,有的可以加index,有的只能cache,做各种水平和垂直提升DB访问量,缓存机制分流。

6,数据库按模块进行迁移拆分:价格 产品 用户 基础设施 订单 商品等,只需要修改数据库连接即可,而对于表字段优化,以SOA收口/应用重构来实现,模块根据业务规模和系统复杂度实现,表名:模块缩写+表名,自增:表名+ID,模块之间减少关联,DB之间不允许join和连接。

7,一号店订单拆分,mod分库比较多,二次分库数据迁移方便,多库简单查询,如带有groupby orderby avg等,建议DAL汇总单个库返回的结果,如按照时间顺序查询订单,没每页面100条,需要遍历所有DB,每个DB中取得前100条,8个汇总为800条,在应用中二次排序,最后取得前面100条。如取第10页数据,汇总后有8000条,读着8000条二次排序后取(900,1000)条记录。

8,外卖涉及三个查询维度:订单ID,用户ID,门店ID,以一定的规则存储每个维度不同的分片,同时按照三个维度多查查询时,数据均在同一个分片。实现1个轻量级的分库分表插件,在业务代码上几个要点:配置文件管理分库分表配置,java注解说明sql语句分库分表,AOP解析注解+查询配置文件获取DB源和表名等,mybatis动态替换表名,spring动态替换数据源,对于ID,用户ID 门店ID外查询(如按照手机号前缀查询)等效率查询,用ES搜索支持,用databus等将订单数据同步到ES,利用批量写入来降低ES写入压力,利用ES分片支持扩展。

9,DB以uid分库分表,二叉树分库,1台->2 台, 2->4,4->8,每个库10个表,订单系统ID为全局唯一序列,利用DB的序列,通过内存计算获取全局唯一的订单ID,三部分组成:毫秒时间,服务器编号,自增序号。

10,,

如何实现高效主键,
1.db方式:这种原理DB里建张序列表,维护序列信息如名称、步长、当前值等,这里步长比较重要,经常有人步长设置为1然后压测性能不行。一般步长设置合适,这块是不会成瓶颈的。db主键的高可用需要后端mysql集群来保证。
2.zk序列:zk序列其实实现了2种,一种是通过zk来协调的非递增,另外一种zk递增方式,递增方式内部实现思路与db方式有点类似,每个表一个序列,然后有个序列步长范围。
3.时间戳方式其实就是Twitter的snowflake,需要每个mycat实例配置的WORKID,DATAACENTERID不同,这块还可以优化下把这个配置放zk上去。
顺便提下:mysql下主键肯定要自增有序的数字类型主键了,UUID那种是不适合的,一个太长,一个是innodb的特性决定的。

11, 如何解决数据扩容
总的思路是设计新分片规则,通过crc32计算出slot,然后把slot映射到物理节点,迁移时先不锁表全量迁移同时记录binlog位置,然后增量迁移,增量追差不多了进行切换。切换时短暂中断写操作。这种方案优点是只有最后切换时才会短暂中断写,而读是不中断,而且只影响被迁移那部分的数据的写操作。这个新分片规则其实跟一致性哈希比较类似,只不过一致性哈希的虚拟节点到物理节点之间映射关系是算法计算的,这样方便后续扩容缩容。
先分片按库预先预留好数量,比如机器不够可以暂时库先放现有的数据库实例上,后续鸭梨大需要扩容了,将分片按库迁移到新的数据库实例上去,其实阿狸的DRDS也是这种思路,实现上相对简单,但是分片数量需要一开始就预留好,后续没法增加,因为本质按分片整个迁移,并未迁移其中数据。
如果细化下去还有很多细节,比如为什么不选择一致性哈希或者其他哈希算法比如张哈希李哈希O(∩_∩)O哈哈~,为什么是crc32而不是crc16,怎样考虑好支持单表千亿以上,分片算法如何高效,如何迁移数量量少,迁移后数据尽量均匀,最后切换为什么选择中断写而不是阻塞住等等,如果一一展开篇幅就太长了


参考:https://www.zhihu.com/question/53494990/answer/135233679

猜你喜欢

转载自blog.csdn.net/zhanjianshinian/article/details/52744244
今日推荐