Spring+iBatis 的多库横向切分简易解决思路(5)

2019-04-21 19:34

com.alibaba.cobar.client.entities.Offer.create partition1 也就是说, 我们现在只定义sqlmap元素, 而忽略

shardingExpression元素的定义, 以上rule定义就好像再说 “只要我发现sqlmap的值是com.alibaba.cobar.client.entities.Offer.create, 那就将匹配的数据访问请求路由到partition1, 而不管参数中的memberId或者其它数据具体是什么 ” .

我们将第一种形式的路由规则成为SqlActionShardingRule, 而将第二种形式的路由规则称为SqlAction(Only)Rule, 分别用于明确的指定在水平切分和垂直切分情况下的路由规则定义.

现在让我们进一步扩展场景, 显然, 除了要创建offer, 我们还要提供更新或者删除等数据操作, 那么, 自然而然的,我们就需要在SqlMap文件中定义更多的sql statement, 如下所示:

... 如果只有SqlActionShardingRule和SqlAction(Only)Rule的支持, 要保证更新和删除操作能够被正确的路由到指定的数据库, 我们就得根据切分规则, 再路由规则定义文件中再为更新和删除操作添加相应的路由规则定义. 这样做的问题在于:

没添加一个针对某表的SqlMap文件, 就需要在路由规则定义文件中添加一系列的CURD操作对应的路由定义, 从使用的角度来看, 很繁琐;

通常针对某个表的操作, 切分规则都是相同的, 不管具体数据访问操作是什么, 也就是说, 通常定义一套路由规则, 原则上来讲应该可以满足CURD多个数据操作的路由.

鉴于以上两点,我们又引入了NamespaceShardingRule和Namespace(Only)Rule的概念.

NamespaceShardingRule允许我们基于SqlMap中的namespace和水平切分规则进行路由规则的定义, 同样针对最初的切分规则, 即memberId为奇数的数据落在数据库1上, 而

memberId为偶数的数据落在数据库2上, 那不管其操作是创建还是更新, 只要数据访问对应的sql statement落在指定的namespace下(对应我们的情况就是

com.alibaba.cobar.client.entities.Offer命名空间), 并且数据访问参数符合指定的切分规则, 我们就可以正确的路由数据访问请求, 最终我们可以给出如下的路由规则定义:

com.alibaba.cobar.client.entities.Offer memberId % 2 == 1 partition1

com.alibaba.cobar.client.entities.Offer memberId % 2 == 0 partition2 进一步的,如果所有数据只是水平切分, 那跟

SqlActionShardingRule和SqlAction(Only)Rule的差别类似, 我们也可以只使用Namespace(Only)Rule:

com.alibaba.cobar.client.entities.Offer partition1

现在, 定义在com.alibaba.cobar.client.entities.Offer命名空间下的所有sql statement, 将全部被路由到partition1数据库执行.

可以看到, 从SqlActionShardingRule到SqlAction(Only)Rule, 一直到NamespaceShardingRule和Namespace(Only)Rule, 路由规则涵盖的面是从特殊到一般层面逐步放开的, 如果针对某个sql statement有特殊的路由需求, 那么可以根据情况添加相应的SqlActionShardingRule或者SqlAction(Only)Rule, 而如果多个sql statement拥有相近或者相同的路由需求, 那么, 就可以根据情况归纳并添加相应的NamespaceShardingRule或者Namespace(Only)Rule, 总之, 这四种类型的Rule类型可以组合使用, 全面的覆盖整个基于iBatis的数据访问请求的路由. Tip

在定义路由规则的过程中,可以从一般情况下的NamespaceShardingRule或者

Namespace(Only)Rule着手, 首先定义一般情况下的路由规则, 然后在根据某些特殊数据访问请求, 进一步添加SqlActionShardingRule或者SqlAction(Only)Rule类型的路由规则.

CobarClientInternalRouter在进行路由的时候, 将首先进行特殊情况下的路由规则匹配, 当找不到匹配规则的时候, 在进一步的使用一般的路由规则作为后备规则进行匹配.

5.2.2.2.3. 自定义路由规则函数(Custom Rule Functions) 常见的水平切分规则有:

基于范围的切分, 比如 memberId > 10000 and memberId < 20000

基于模数的切分, 比如 memberId8==1 或者 memberId8==2 或者...

基于哈希(hashing)的切分, 比如hashing(memberId)==someValue等

另外, 还有诸如predicate-based partitioning等, 为了满足不同切分规则定义的需要, 我们运行在路由规则定义的时候, 在shardingExpression中使用自定义的路由规则函数.

下面我们以一个简单的实例来说明在Cobar Client中如何自定义使用路由规则函数.

假设我们要按照某种hashing算法对memberId进行散列, 并根据散列的值进行路由, 那么首先,我们需要定义一个函数类, 该类将根据传入的memberId返回相应的散列结果:

public class Hashing{ ... int apply(Long memberId){ // perform real logic here. } } 有了该函数定义,我们希望在shardingExpression中使用它, 那首先我们需要注册该函数, 这通过CobarInteralRouterXmlFactoryBean的 “functionsMap ”

属性进行:

classpath:META-INF/routing/offer-sql-action-rules.xml classpath:META-INF/routing/offer-sharding-rules-on-namespace.xml 注意,我们以hash作为key对以上自定义函数进行了注册.

有了以上准备之后, 我们就可以在shardingExpression中使用该自定义函数了:

com.alibaba.cobar.client.entities.Offer

hash.apply(memberId) == someValue partition1

com.alibaba.cobar.client.entities.Offer

hash.apply(memberId) == anotherValue partition2 可见只要使用注册时用的key作为对象应用针对指定的表达式字段调用相应的方法就是了. 简单, 却不失强大.

5.2.3. SqlAuditing

CobarSqlMapClientTemplate提供了针对SQL的分析和记录扩展接口,但没有给出相应的实现, 因为国际站现在可以通过Ark项目来完成同样的目的, 但如果需要, 可以给出一个ISqlAuditor接口实现, 然后注入给CobarSqlMapClientTemplate.

ISqlAuditor接口定义很简单:

public interface ISqlAuditor { void audit(String id, String sql, Object sqlContext); } 其中, 参数\标志执行的iBatis的sqlmap的id; 参数 “sql ” 表示id对应的SQL, 如果id对应的SQL是DynamicSql的话, 该参数为null; 最后参数sqlContext对应具体传入的参数对象. 应用程序可以根据具体场景来决定如何实现某个ISqlAuditor以及如何使用这些参数.为了不影响性能, 提供的ISqlAuditor尽量采用异步的方式进行处理, 不要同步阻塞后续的数据访问请求的处理.

如果为CobarSqlMapClientTemplate注入某个ISqlAuditor的实现, 那么默认情况下

CobarSqlMapClientTemplate会检查用户是否同时注入了一个伴随的ExecutorSerivce, 该伴随的ExecutorService主要是为了避免用户提供的ISqlAuditor没有进行合适的异步处理策略从而拖累CobarSqlMapClientTemplate的情况发生, 如果用户没有提供这样一个ExecutorService, 那CobarSqlMapClientTemplate会默认初始化一个拥有一个worker thread的ExecutorService. 原则上用户不需要干预该ExecutorService, 但如果调整该参数对CobarSqlMapClientTemplate的性能有帮助的话,那可以通过 sqlAuditorExecutor 属性来注入一个外部的ExecutorService.

5.2.4. 其它配置与特性解释(Other Configuration or Features Explained) 5.2.4.1. 记录长时间运行的SQL功能

应监控需求, 我们在CobarSqlMapClientTemplate中加入了记录长时间运行的SQL功能, 该功能默认情况下为不开启,如果要开启该功能, 可以通过设置 profileLongTimeRunningSql 属性来完成. 设置 profileLongTimeRunningSql 的同时, 我们同时要求提供监控的SQL运行时间的限定标准, 即 longTimeRunningSqlIntervalThreshold , 如果用户提供的

longTimeRunningSqlIntervalThreshold小于或者等于零, 在CobarSqlMapClientTemplate初始化的时候将抛出异常, 以阻止用户使用非状态完备的CobarSqlMapClientTemplate实例.

配置该功能的简单实例如下:

class=\ ... 5.2.4.2. 批量插入功能

某些情况下, 应用程序可能会通过 “INSERT INTO tab(..) VALUES(..), (..), (..), (..)... ” 形式的SQL进行批量的数据插入, 为了支持这种情况, CobarSqlMapClientTemplate允许通过BatchInsertTask来提交批量的插入数据, 当CobarSqlMapClientTemplate发现在insert(..)的时候用户传入的是BatchInsertTask类型的参数的话, 它首先会根据路由规则对提交的批量数据进行重新归类, 将发送到不同DataSource的数据归类到不同的队列中, 归类完成之后, 再并行的提交给不同的DataSource执行.


Spring+iBatis 的多库横向切分简易解决思路(5).doc 将本文的Word文档下载到电脑 下载失败或者文档不完整,请联系客服人员解决!

下一篇:复变函数与积分变换试题1

相关阅读
本类排行
× 注册会员免费下载(下载后可以自由复制和排版)

马上注册会员

注:下载文档有可能“只有目录或者内容不全”等情况,请下载之前注意辨别,如果您已付费且无法下载或内容有问题,请联系我们协助你处理。
微信: QQ: