利用h5来做一个分布式的kv磁盘存储工具
Project description
为什么要用h5
比如需要将一个词典保存到磁盘,词典很小直接pickle.dumps就行,读取也直接pickle.loads, 但是当词典很大,比如一亿的时候,这时候可能需要做一些操作
将词典分割,分次很多份分别存储
使用h5
第一种方法存起来没什么问题,但是随机读取会很慢,比如一批random的key,key可能分散在所有的分片中,因此需要将所有的词典load到内存一遍,耗费大量时间。 这应该是一个经典的数据库的问题,但是有时候又不想用很重的数据库,可选项就剩下
使用轻量级的数据库,例如sqlite3、leveldb等
使用h5
前者不在我们今天的讨论范围,这里主要是讲一下h5的一些性能实测,和一些高效使用的方法。
读写测试
关于groups
一般来讲的话先建groups,再建dataset,理论上groups越多,读写效率越高。 在MacBook Pro 16-inch, 2019上的测试数据如下:
Item |
groups=1 |
groups=10 |
groups=100 |
groups=1000 |
---|---|---|---|---|
10w数据内存峰值(M) |
96.3 |
92.9 |
97.4 |
101 |
10w数据插入时间 |
19.06 |
19.08 |
19.31 |
21.51 |
10w数据读取1w条 |
2.46 |
2.59 |
2.65 |
2.58 |
100w数据插入时间 |
188.34 |
190.99 |
190.16 |
199.78 |
100w数据读取1w条 |
4.35 |
5.82 |
4.14 |
4.28 |
1000w数据插入时间 |
~ |
~ |
~ |
约1小时 |
1000w数据读取1w条 |
~ |
~ |
~ |
9.92 |
前面10w和100w试验的时候,差距很小,甚至groups=1反而更快。但是当数据量提升到1000w的时候,差距变得很明显, group=1的情况无法完成, groups=100和1000至少相差一倍时间。
结论就是在数据量极大的情况下,必须用多个ngroups。
多进程/线程同时读
注意直接多进程,会有一些问题;需要这样,加入swmr(single write multiple read)
h5py.File('./data_1000.h5', 'r', swmr=True)
下面是一个300w的数据库,单/多进程测试结果:
n_process = 1 |
n_process = 2 |
n_process = 10 |
n_process = 100 |
|
---|---|---|---|---|
0.1w条query |
0.66 |
0.27 |
0.13 |
0.28 |
1w条query |
8.8 |
4.3 |
1.1 |
1.3 |
10w条query |
67.9 |
34.4 |
7.9 |
8.21 |
可以看出来,多进程读效果提升非常明显,但是肯定也不是越多越好,带来很多额外开销。
关于blocks大小
测试方法,30w次读写速度,测试单次插入数据量的大小对最终结果的影响
单次插入数据量 |
0.1k |
1k |
10k |
100k |
---|---|---|---|---|
写入时间(秒) |
60.25 |
62.25 |
66.96 |
195.95 |
1w次读取时间(秒) |
2.52 |
2.6 |
5.88 |
7.91 |
可以看出来,读取速度对blocks大小敏感度没有那么大,数据量增大1000倍,读取时间增长到3倍,写入速度也是三倍,但是并非线性。
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.