MongoDB存储的行情数据如何选择合适的Shard Key

发布于: 雪球转发:0回复:0喜欢:0

当利用MongoDB的shard cluster技术做数据库扩展时,一个至关重要的点是要选择一个合适的shard key(片键),它用来决定将数据在分片服务器上分配的策略。一个适用的shard key应该满足以下几个条件:

1.数据均分 所谓数据均分,就是要保证需要扩展的那部分数据能够尽可能平均分配到数据分片上,以达到空间上的扩展目的。

2.负载均分

负载均分是把应用访问的分片数据的负载平均分配到数据分片集群上,应用对数据的访问要划分读写分析。

3.方便扩展 

一般情况下,数据库的扩展都不是一次完成的,以后可能还需要对数据进一步分片,因此这次的设计方案,要尽可能为后续的扩展留下余地,而不是每一次都要推倒重来。


MongoDB的片键分类


MongoDB支持两种类型的shard key

Hashed,数据库根据指定的字段值,算出一个哈希值,然后根据这个哈希值把数据写入相应的服务器中。它的好处是数据会分布的比较均匀,但是它只能把一个字段指定为shard key,另外对于范围的操作,它更多是一个广播的操作,没有精确地路由。

Ranged,按照指定字段的值的范围进行划分,支持复合shard key。这个就要求对字段值的范围有比较深入的了解,对未来也有一个相对清晰的把握。相对哈希,这种方式就可以有比较精确的路由。但是它也可能会带来数据分布不均匀,负载不能完全均衡的问题。


实例

下面以实例说明一下,如何选择合适的shard key。假设我们要分布的是分钟级别的K线显示,数据样例如下:

为了操作方便,把各个分钟级别的数据都存放在了一起,如果拆表,会对业务造成很大伤害,改动较多。因此考虑对该表做sharding。


那么我们该如何选择shard key呢?

在回答这个问题之前,我们首先要看下最常用的操作有哪些。

首先是写入操作,基本上是一次性的,之后很少会进行变更。
其次就是查询操作,我们看下面两个典型的操作:

通过上面两个查询不难看出两个关键字段是code和period,同时要提高查询效率,我们需要使用精确路由,因此我们选用Ranged类型的shard key。那么范围应该如何划分呢?对于code,我们可以按照前两位或者前三位划分,它的问题是数据分布不均衡,因为每种类型的股票个数不一样;对于period,我们可以根据数量来划分,简单计算一下就知道一只股票一天的1分钟线是240根(不包含集合竞价)、60分钟线4根、5分钟线24根,那么根据这个数据量我们把一分钟线放到一台服务器上,其他分钟线放在其他服务器上。


按照之前的分析,数据均分和负载均分的问题基本解决了,接下来就要看扩展了。我们从数据规模来看,只需要再按照股票代码做划分即可。