加入收藏 | 设为首页 | 会员中心 | 我要投稿 核心网 (https://www.hxwgxz.com/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程 > 正文

从分库分表后遗症,总结数据库表拆分策略

发布时间:2018-08-16 05:02:15 所属栏目:编程 来源:王清培(沪江)
导读:技术沙龙 | 邀您于8月25日与国美/AWS/转转三位专家共同探讨小程序电商实战 本文将主要从背景、分库分表带来的后遗症、分表策略以及一些注意事项等方面对数据库分表来进行小结。 一、背景 最近一段时间内结束了数据库表拆分项目,本次拆分主要包括订单和优惠

在我们熟悉的HashMap里,为了减少冲突和提供一定的性能将Hash桶的大小设置成2的n次方,然后采用Hash&(legnth-1)位与的方式计算,这样主要是大师们发现2的n次方的二进制除了高位是0之外所有地位都是1,通过位与可以快速反转二进制然后地位加1就是最终的值。

我们在做数据库Sharding的时候不需要参考这一原则,这一原则主要是为了程序内部Hash表使用,外部我们本来就是要Hash mod确定Sharding node 。

通过mod取模的方式会出现不均匀问题,在此基础上可以做个自定义奇偶路由,这样可以均匀两边的数据。

四、一些注意事项

1、在现有项目中集成Sharding-JDBC有一些小问题,Sharding-JDBC不支持批量插入,如果项目中已经使用了大量的批量插入语句就需要改造,或者使用辅助hash计算物理表名,再批量插入。

2、原有项目数据层使用Druid + MyBatis,集成了Sharding-JDBC之后Sharding-JDBC包装了Druid ,所以一些Sharding-JDBC不支持的SQL语句基本就过不去了。

3、使用Springboot集成Sharding-JDBC的时候,在bean加载的时候我需要设置 IncrementIdGenerator ,但是出现classloader问题。I

  1. IncrementIdGenerator incrementIdGenerator = this.getIncrementIdGenerator(dataSource); 
  2.  
  3. ShardingRule ShardingRule = ShardingRuleConfiguration.build(dataSourceMap); 
  4.  
  5. ((IdGenerator) ShardingRule.getDefaultKeyGenerator()).setIncrementIdGenerator(incrementIdGenerator); 
  6.  
  7. private IncrementIdGenerator getIncrementIdGenerator(DataSource druidDataSource) { 
  8.  
  9. ... 
  10.  
  11.     } 

后来发现Springboot的类加载器使用的是restartclassloader,所以导致转换一直失败。只要去掉spring-boot-devtools package即可,restartclassloader是为了热启动。

4、dao.xml逆向工程问题,我们使用的很多数据库表MyBatis生成工具生成的时候都是物理表名,一旦我们使用了Sharding-JDCB之后都是用的逻辑表名,所以生成工具需要提供选项来设置逻辑表名。

5、为MyBatis提供的SqlSessionFactory需要在Druid的基础上用Sharding-JDCB包装下。

6、Sharding-JDBC DefaultkeyGenerator默认采用是snowflake算法,但是我们不能直接用我们需要根据datacenterid-workerid自己配合Zookeeper来设置 workerId 段。

(snowflake workId 10 bit 十进制 1023,dataCenterId 5 bit 十进制 31 、WorkId 5 bit 十进制 31)

7、由于我们使用的是mysql com.mysql.jdbc.ReplicationDriver自带的实现读写分离,所以处理读写分离会方便很多。如果不是使用的这种就需要手动设置Datasource Hint来处理。

8、在使用MyBatis dao mapper的时候需要多份逻辑表,因为有些数据源数据表是不需要走Sharding的,自定义ShardingStragety来处理分支逻辑。

9、全局ID几种方法:

  • 如果使用 Zookeeper来做分布式ID,就要注意session expired可能会存在重复workid问题,加锁或者接受一定程度的并行(有序列号保证一段时间空间)。
  • 采用集中发号器服务,在主DB中采用预生成表+incrment 插件(经典取号器实现,InnoDB存储引擎中的TRX_SYS_TRX_ID_STORE 事务号也是这种方式)。
  • 定长发号器、业务规则发号器,这种需要业务上下文的发号器实现都需要预先配置,然后每次请求带上获取上下文来说明获取业务类型。

10、在项目中有些地方使用了自增ID排序,数据表拆分之后就需要进行改造,因为ID大小顺序已经不存在了。根据数据的最新排序时使用了ID排序需要改造成用时间字段排序。

【编辑推荐】

  1. 是什么影响了数据库索引选型?
  2. 数据库插入或者更新大批量数据的性能优化
  3. 静默错误:Oracle数据库是如何应对和处理的 ?
  4. 【工具】数据库设计中的6个最佳实践步骤
  5. 面试中有哪些经典的数据库问题?
【责任编辑:庞桂玉 TEL:(010)68476606】
点赞 0

(编辑:核心网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

热点阅读