分库分表实战
方案:
1.分表分库框架选型sharding-jdbc
2.分库后使用雪花算法代替mysql主键id自增
3.拆分规模:拆分到8个库,每库8张表
4.分片算法:用户号作为数据库和表的分片键,路由算法:数据库路由 = ((Math.abs(user_no.hashCode())%64)/8).toInteger(),表路由= (Math.abs(user_no.hashCode())%8)
5.使用本地事务(https://shardingsphere.apache.org/document/legacy/3.x/document/cn/features/transaction/local-transaction/),整个领域聚合体切分,维度一致,所以对聚合体的事务是支持的
6.历史数据迁移和校验使用架构组提供的scaling工具
sharding-jdbc分库分表配置如下
<!-- 分库策略 根据id取模确定数据进哪个数据库 -->
<sharding:inline-strategy id="databaseStrategy" sharding-column="user_no" algorithm-expression="ds$->{((Math.abs(user_no.hashCode())%64)/8).toInteger()}" />
<!-- 分表策略 根据id取模确定数据进哪个表 -->
<sharding:inline-strategy id="orderTableStrategy" sharding-column="user_no" algorithm-expression="t_order_$->{Math.abs(user_no.hashCode())%8}" />
<!-- 主键ID生成策略 -->
<bean:properties id="properties">
<prop key="worker.id">123</prop>
</bean:properties>
<sharding:key-generator id="sharding_id_KeyGenerator" type="TEST_SNOWFLAKE" column="id" props-ref="properties" />
<sharding:data-source id="shardDataSource">
<sharding:sharding-rule data-source-names="ds0,ds1,ds2,ds3,ds4,ds5,ds6,ds7" default-data-source-name="ds0">
<sharding:table-rules>
<sharding:table-rule logic-table="t_order" actual-data-nodes="ds$->{0..7}.t_order_$->{0..7}" database-strategy-ref="databaseStrategy" table-strategy-ref="orderTableStrategy"/>
</sharding:table-rules>
<sharding:binding-table-rules>
<sharding:binding-table-rule logic-tables="t_order"/>
</sharding:binding-table-rules>
</sharding:sharding-rule>
<sharding:props>
<prop key="sql.show">${test.sharding.sql.show:false}</prop>
<prop key="sql.simple">${test.sharding.sql.simple:false}</prop>
</sharding:props>
</sharding:data-source>
总结:
1.分片算法调整为官方建议的标准分库算法shardingkey=hash(userNo)
2.拆分规模尽量选择2幂次方,最终选择8个库,每个库8个表
3.测试和生产环境保持保持一致的水平分库
4.整个实施过程要有完备的热切开关操作,保证可回滚
5.尽量在业务开发过程中避免没有分片键的sql查询或者写入
6.不要在sql中使用shardingsphere不支持sql关键字。例如ifnull,或者使用可替换方法
7.历史数据迁移过程中,sql中不要使用数据库自身生成的时间,例如now(),在双写过程中,会有先后写入会导致原库和分库写入瞬时时间不一致。应使用应用服务器生成时间
8.打印日志可以查看sql的执行内容。但是不能观测到shardingsphere内部的sql解析,路由,改写,执行,归并的性能,后续可以考虑和skywalking结合,观测shardingsphere内部执行性能。
9.发现项目启动后sharding-jdbc第一次做sql解析词法。比较慢,需要在项目启动后立即做SQL预热。