策略一
结合分片总数和当前分片,分页加载处理想要表数据,如下所示:
//分片参数
ShardingVO shardingVO = ShardingUtil.getShardingVo();
int i=0;
int pageNo=1;
//执行器数量
int total = shardingVO.getTotal();
//当前分片(下标从0开始)
int index = shardingVO.getIndex();
WearUserQuery wearUserQuery;
do{
wearUserQuery = new WearUserQuery();
//页码以分片+分片总数
wearUserQuery.setPageNo(index+pageNo);
wearUserQuery.setPageSize(20);
wearUserQuery.createCriteria().andFirstCommunicationTimeIsNotNull();
List<WearUser> wearUsers = wearUserService.selectWearUserByQuery(wearUserQuery);
i = wearUsers.size();
for (WearUser wearUser : wearUsers) {
//do something
}
//页码以分片+分片总数
pageNo+=pageNo+total;
}while(i>=20);
以上代码中的缺点:
- 增加数据库访问量,执行效率慢
- 若执行过程中某个分片宕机了,就会重复加载处理数据
策略二
每个分片一次性读取要处理的数据,根据当前分片取模处理属于各自的数据
//分片参数
ShardingVO shardingVO = ShardingUtil.getShardingVo();
WearUserQuery wearUserQuery = new WearUserQuery();
wearUserQuery.createCriteria().andFirstCommunicationTimeIsNotNull();
List<WearUser> wearUsers = wearUserService.selectWearUserByQuery(wearUserQuery);
int i = wearUsers.size();
for (int j = 0; j < i; j++) {
//对数据下标以当前分片取模选取处理
if (j % shardingVO.getTotal() == shardingVO.getIndex()) {
//do something
}
}
以上代码如果执行节点1挂了,那么执行节点1的分片,将自动转移到执行节点2或者执行节点3执行,达到分片的高并发,高可靠。
策略三
创建计数器,起始记录记录在redis,每个机器的本地记录,处理多少条添加到redis,每片要处理前个取值从redis中取起始数
//分片参数
ShardingVO shardingVO = ShardingUtil.getShardingVo();
int i=0;
int pageNo=1;
//执行器数量
int total = shardingVO.getTotal();
//当前分片(下标从0开始)
int index = shardingVO.getIndex();
WearUserQuery wearUserQuery;
Jedis() jd=new Jedis()
do{
sleep(index*1000); //根据下标挂起,后面的依次读取
int startRow+20 =(int)jd.get("startRow")
pageNo=startRow/20
//页码以分片+分片总数
jd.set("startRow",startRow+20);
wearUserQuery = new WearUserQuery();
//页码以分片+分片总数
wearUserQuery.setPageNo();
wearUserQuery.setPageSize(pageNo);
wearUserQuery.createCriteria().andFirstCommunicationTimeIsNotNull();
List<WearUser> wearUsers = wearUserService.selectWearUserByQuery(wearUserQuery);
i = wearUsers.size();
for (WearUser wearUser : wearUsers) {
//do something
}
}while(i>=20);
所有的机器读取同一个起始位置,则不会出现重复处理的情况