百万级 Hash,十亿个元素,分布式存储和索引选什么适合?

2020-02-04 20:34:35 +08:00
 dusu

背景

各位大佬好,目前小弟手上有百万级的 Hash,约十亿个元素,格式如下:


00000001
  |-key=a, val=2 字符:[1-20]-crc32 字符:整数 1:整数 2
  |-key=b, val=2 字符:[1-20]-crc32 字符:整数 1:整数 2
  ...
  |-key=z, val=2 字符:[1-20]-crc32 字符:整数 1:整数 2
  

00000002
  |-key=aa, val=2 字符:[1-20]-crc32 字符:整数 1:整数 2
  |-key=bb, val=2 字符:[1-20]-crc32 字符:整数 1:整数 2
  ...
  |-key=zz, val=2 字符:[1-20]-crc32 字符:整数 1:整数 2
  
...

value 格式:

一个元素代表一个文件:

2 字符:代表所在的机器

[1-20]-crc32:代表目标所在文件

整数 1:代表目标在文件的起始位置

整数 2:代表文件长度

---例子---

ab:9-cbdg3323:1200:500

每个 Hash 的 key 大概在 100-5000 个。

目前场景读大于写(读约 500/s,写约 200/s ),方案用的是 ssdb,

ssdb 单线程 compact 的时候对服务影响太大,经常 loadavg 过载

加上另外,leveldb 层面似乎更适合读大于写的场景(还有部署机器也不一定是 SSD 硬盘)。

对比

对比过市面上类似产品:Pika\Ledis\redix(主要对比了不同存储引擎),似乎效果相差不大。

为什么不选 Redis?

成本问题,目前 ssdb 已经快 100G 了,

再加上要求分布式的话,如果能把这 十亿个元素 x5 倍 存在可观的 Redis 中,也可以考虑。

SO. 求大佬推荐一下适合的产品(或技术方案)。

要求:

  1. 支持「分布式」,扩容无忧
  2. 可支持高效在 hash 中「批量」检查元素 key 是否存在
  3. 高效的读大于写的场景,读 QPS 能达到目前的 5x
  4. 最好有现成的 redis/http 协议可开箱用
  5. 全家桶性质的产品慎推,不想引入太多运维成本

备用方案:

按 id 水平拆表存 mysql,将元素里的数据拆开来存储、索引.

再加前置缓存...

5509 次点击
所在节点    程序员
26 条回复
vus520
2020-02-04 21:15:35 +08:00
如果你的 key 读写不多,可以考虑 db 或者 ES。
如果都是缓存级别的热数据,那估计 pika 是最好的,现在 SSD 不贵。
fuis
2020-02-04 21:28:27 +08:00
tidb
dusu
2020-02-04 21:54:11 +08:00
@vus520
感谢,pika 其实挺好的,但是到 v3 后已经去掉 double master 支持了,
要自行引入 codis,不然还得带 docker,运维成本并不低
之前用 pika 当文件存储服务,存了 1.5T 文件后,
访问量不高,但 I/O 直接吃满,性能上不去,就不敢用了...

@fuis
感谢,TIDB 门槛有点高,个人开发者吃不消.
vus520
2020-02-04 22:21:04 +08:00
那就 mongo 或者 ES 了
ppyybb
2020-02-05 00:15:41 +08:00
写入是指更新还是增加一个 key ? hash 数量会变化吗? latency 要求是啥
ppyybb
2020-02-05 01:01:49 +08:00
你这个限制比较多,又要省钱....要不自己搭建一个 mongo 集群,要不自己搭建 ssdb 集群(运维成本,改动小点),要不试试阿里云混合存储 redis ?
btnokami
2020-02-05 03:13:05 +08:00
现在是 single instance 吗?搭一个 cluster 然后对 key 做 partition 应该能 scale 起来吧,或者用 Master slave model,只有 write to master 然后 read from slave 应该可以解决吧
laminux29
2020-02-05 05:15:39 +08:00
1.海量数据,又要关键操作性能高,这种情况下,读与写本来就是个矛盾,要不读快写满,要不写快读满,你要两者都高,这怎么可能。

2.你对开源(免费)产品,既要求性能高,又要求功能多,还要求运维成本低,这怎么可能。

3.在一堆海量数据里,确定一条数据的唯一性,这本来就是世界难题,原因是在硬件与运维有限的前提下,这操作完全是在挑战计算机设备的性能极端,这事在理论上根本没办法搞定,就连谷歌最后都只能选择砸钱堆服务器堆运维,才有了较好的性能。你又没服务器,又没人给你运维数据性能,这事怎么可能解决得了?

建议:
1.你应该选择你最关注的因素,比如读速度快,然后牺牲一下写数据,按这个模式,来做业务逻辑。


2.现在任何一款主流的分布式数据库,都做不到帮你把冷热数据均摊好,保证每台物理设备的性能平均。因为这个操作要涉及到经常的大规模的数据迁移,这个过程本身就会大幅度降低系统性能。因此,还不如你自己设计一个冷热数据记录器,再根据业务繁忙度,在闲时就像停服一样,重新分布冷热数据。这操作其实就是运维工作,你不去做这个工作,没办法把冷热数据高质量地均摊在不同物理设备上。
raynor2011
2020-02-05 07:25:55 +08:00
Hbase?
xautll
2020-02-05 08:57:23 +08:00
clickhouse 可以参考一下
sampeng
2020-02-05 09:06:31 +08:00
redis 完全够用…才百万级和 10 亿个元素…你也太小看 redis 了
defunct9
2020-02-05 10:44:03 +08:00
楼主最后用什么?
cabing
2020-02-05 10:48:28 +08:00
@dusu

算下成本。你的存储时 100G 吗?

如果觉得 redis 成本高的话,

单机的 io 又比较大,为啥不自己写个简单的 proxy 呢?

底层挂哪个存储都行,ssdb 或者 pika 或者直接用 rocksdb 做个存储也行。
dusu
2020-02-05 13:07:52 +08:00
@ppyybb 感谢,目前用的就是 ssdb 集群。
dusu
2020-02-05 13:10:51 +08:00
@btnokami 目前是集群 回头试试 key 分片。
dusu
2020-02-05 13:12:24 +08:00
@xautll 似乎 clickhouse 适合于离线分析 ,不适合高并发下 kv 查询。
wingyiu
2020-02-05 13:13:14 +08:00
redis 分片方案呗
dusu
2020-02-05 13:15:19 +08:00
@laminux29 大佬说的是,问题描述确实有些矛盾,其实也是想请教一下在这个场景下,大家会用的一些低成本高收益的方案。
dusu
2020-02-05 13:18:06 +08:00
@cabing 自己做 proxy 其实也尝试过 单机问题不大。但是涉及到「分布式」这块一致性和稳定性比较难彻底解决。遂放弃。
cabing
2020-02-05 13:23:38 +08:00
@dusu


分布式的 meta,使用 consul 或者 etcd 存下 meta 信息。

比较简单方案:做个一致性 hash,然后每个 node 都自己做个简单的拷贝方案,分布式存储存下 meta,这个最简单啊

需要改造,获取数据时做个 proxy 改造

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/642148

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX