Zebra分库分表的使用

本文只说明如何使用zebra进行分库分表,不涉及原理源码

一 数据源配置文件

<bean id="shardDataSource" class="com.dianping.zebra.shard.jdbc.ShardDataSource" init-method="init">
        <!-- lion配置方式,需配置shardds.xxx.shard项value为json格式 --> //所以实际对应的rule的配置的key是shardds.trade.shard
        <property name="ruleName" value="trade"/>

        <!-- 主动配置分库,lion配置下可选,xml配置必输 -->
        <property name="dataSourcePool">//这里能做分库的原因就是用一个map就可以配多个数据库了
            <map>
                <entry key="ds0" value-ref="dataSource2"/><!-- 该处的key即为配置里面的dbIndexes --> // ds0可以根据开发习惯起名的,也可以叫db0...
            </map>
        </property>

        <!-- 内部写线程池参数,默认32-64-5000 拒绝策略-报错 -->
        <property name="parallelCorePoolSize" value="8"/>
        <property name="parallelMaxPoolSize" value="24"/>
        <property name="parallelWorkQueueSize" value="1000"/>
        <!-- 内部读线程池参数,默认32-64-5000 拒绝策略-报错 -->
        <property name="readWriteSplitPool" value="true"/>
        <property name="readParallelCorePoolSize" value="24"/>
        <property name="readParallelMaxPoolSize" value="24"/>
        <property name="readParallelWorkQueueSize" value="1000"/>
        <!-- 并行度设置 -->
        <property name="concurrencyLevel" value="8"/>
        <!-- 内部执行器设置任务超时时间,默认:1000ms -->
        <property name="parallelExecuteTimeOut" value="5000"/>
    </bean>

 

<bean id="dataSource2" class="com.dianping.zebra.group.jdbc.GroupDataSource" init-method="init">
        <property name="jdbcRef" value="trade"/> //这个就是特色了 会根据value里的值,构造key去lion中查询值
        <property name="initialPoolSize" value="10"/>
        <property name="minPoolSize" value="10"/>
        <property name="maxPoolSize" value="45"/>
        <property name="checkoutTimeout" value="3000"/>
        <property name="maxIdleTime" value="1800"/>
        <property name="idleConnectionTestPeriod" value="1800"/>
        <property name="acquireRetryAttempts" value="3"/>
        <property name="acquireRetryDelay" value="300"/>
        <property name="maxStatements" value="0"/>
        <property name="maxStatementsPerConnection" value="100"/>
        <property name="numHelperThreads" value="6"/>
        <property name="testConnectionOnCheckin" value="false"/>
        <property name="testConnectionOnCheckout" value="true"/>
        <property name="maxAdministrativeTaskTime" value="5"/>
        <property name="preferredTestQuery" value="SELECT 1"/>
        <property name="extraJdbcUrlParams" value="connectTimeout=1000" />
    </bean>

 

这个GroupDataSource就是实现读写分离的关键,一个GroupDataSource 都会包含至少两个SingleDataSource。这里找的过程大概是这样的

根据trade拼出来key,groupds.trade.mapping 然后再拿着这个key找value

比如我们公司的lion中的配置就是这样的 

 keygroupds.trade.mapping value (trade-m1-read:1),(trade-m1-write) 

 

接下来才是通过上一步得到的每个读写数据库的名字获取jdbc的url

比如在lion中保存jdbc的key为 ds.trade-m1-write.jdbc.url这其中的trade就是用jdbcRef的value拼出来的

公司的key-value是这样的 

ds.trade-m1-write.jdbc.url jdbc:mysql://wnojrdevmysql.service.dev.consul:3306/trade?characterEncoding=utf8&

二 分库分表规则

注意到上面的ShardDataSource中的一个配置项

 <property name="ruleName" value="trade"/> 
那么这个ruleName是怎么找到的呢?答案就是到lion上找的
最后会拼出来一个key shardds.trade.shard
找出来的value是这样的。这里配置项很多,只选取一个订单表来说明
{
    "tableShardConfigs": [
        
        {
            "tableName": "tp_order",
            "dimensionConfigs": [
                {
                    "dbRule": "#id#.longValue()  %  1",
                    "dbIndexes": "ds0",
                    "tbRule": "(#id#>>17)  %  64",
                    "tbSuffix": "everydb:[_0,_63]",
                    "isMaster": true
                }
            ],
            "generatedPK": "id"
        },
  • dbRule 分库规则,按照订单的id进行分库,由于是 %1,所以在dev下我们只有一个数据库
  • dbIndexes 上面配数据源的地方配的数据源key,上面配的是ds0,所以这里也得是ds0.如果是多个数据库可以这么配 db[0-3]。
  • tbRule 分表规则,很好理解,id右移17位后取模64,表示分64张表
  • tbSuffix 表名后缀,everydb表示每个库下都有64张表0-63,该配置还可以alldb,如果是两个库,表名就是0-127了
  • isMaster 这里就比较复杂了,就是说分库分表规则是根据一个字段来进行,配置为true说明是不是主字段,一般像订单表orderid就够了

如何强制走主库

在写sql的时候加上这句

/*+zebra:w*/SELECT
        <include refid="Base_Column_List"/>
        FROM tp_order_bill_item WHERE order_id = #{orderId} and is_valid = 1

 

posted on 2021-05-27 17:23  MaXianZhe  阅读(769)  评论(0编辑  收藏  举报

导航