1.水平分区下的查询
对于简单查询Hibernate Shard可以满足。
水平分区下多库查询是一个挑战。主要存在于以下三种操作:
1) distinct因为需要遍历所有shard分区,并进行合并判断重复记录。
2) order by类似 1)
3) aggregation count,sim,avg等聚合操作先分散到分区执行,再进行汇总。
是不是有点类似于 MapReduce ? 呵呵。
Hibernate Shard 目前通过 Criteria 接口的实现对 聚合提供了较好的支持, 因为 Criteria 以API接口指定了 Projection 操作,逻辑相对简单。而HQL,原生 SQL 还不支持此类操作。
2. 再分区和虚拟分区
当数据库规模增大,需要调整分区逻辑和数据存储时, 需要再分区。
两种方式:
1)数据库数据迁移其他分区;
2)改变记录和分区映射关系。这两种方式都比较麻烦。尤其“改变记录和分区映射关系”,需要调整 ShardResolutionStrategy.
Hibernate Shard 提供了一种虚拟分区层。当需要调整分区策略时,只需要调整虚拟分区和物理分区映射关系即可。以下是使用虚拟分区时的配置创建过程:
Java代码
- Map<Integer, Integer> virtualShardMap = new HashMap<Integer, Integer>();
- virtualShardMap.put(0, 0);
- virtualShardMap.put(1, 0);
- virtualShardMap.put(2, 1);
- virtualShardMap.put(3, 1);
- ShardedConfiguration shardedConfig =new ShardedConfiguration
(prototypeConfiguration,configurations,strategyFactory,virtualShardMap);- return shardedConfig.buildShardedSessionFactory();
3.局限:
1)Hibernate Shard 不支持垂直分区, 垂直+水平混合分区。
2)水平分区下 查询功能受到一定限制,有些功能不支持。实践中,需要在应用层面对水平分区算法进行更多的考虑。
3)不支持跨分区的 关系 操作。例如:删除A分区上的 s 表,B分区上的关联子表 t的记录无法进行参照完整性约束检查。 (其实这个相对 跨分区查询的挑战应该说小的多,也许google工程师下个版本会支持,呵呵)
4)解析策略接口似乎和对象ID全局唯一性有些自相矛盾,AllShardsShardResolutionStrategy 的接口返回的是给定对象ID所在的 shard ID集合,按理应该是明确的一个 shard ID.
【编辑推荐】