各位大佬好,目前小弟手上有百万级的 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
...
一个元素代表一个文件:
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(主要对比了不同存储引擎),似乎效果相差不大。
成本问题,目前 ssdb 已经快 100G 了,
再加上要求分布式的话,如果能把这 十亿个元素 x5 倍 存在可观的 Redis 中,也可以考虑。
SO. 求大佬推荐一下适合的产品(或技术方案)。
按 id 水平拆表存 mysql,将元素里的数据拆开来存储、索引.
再加前置缓存...
1
vus520 2020-02-04 21:15:35 +08:00 1
如果你的 key 读写不多,可以考虑 db 或者 ES。
如果都是缓存级别的热数据,那估计 pika 是最好的,现在 SSD 不贵。 |
2
fuis 2020-02-04 21:28:27 +08:00
tidb
|
3
dusu OP |
4
vus520 2020-02-04 22:21:04 +08:00 1
那就 mongo 或者 ES 了
|
5
ppyybb 2020-02-05 00:15:41 +08:00 via iPhone
写入是指更新还是增加一个 key ? hash 数量会变化吗? latency 要求是啥
|
6
ppyybb 2020-02-05 01:01:49 +08:00 via iPhone
你这个限制比较多,又要省钱....要不自己搭建一个 mongo 集群,要不自己搭建 ssdb 集群(运维成本,改动小点),要不试试阿里云混合存储 redis ?
|
7
btnokami 2020-02-05 03:13:05 +08:00
现在是 single instance 吗?搭一个 cluster 然后对 key 做 partition 应该能 scale 起来吧,或者用 Master slave model,只有 write to master 然后 read from slave 应该可以解决吧
|
8
laminux29 2020-02-05 05:15:39 +08:00 1
1.海量数据,又要关键操作性能高,这种情况下,读与写本来就是个矛盾,要不读快写满,要不写快读满,你要两者都高,这怎么可能。
2.你对开源(免费)产品,既要求性能高,又要求功能多,还要求运维成本低,这怎么可能。 3.在一堆海量数据里,确定一条数据的唯一性,这本来就是世界难题,原因是在硬件与运维有限的前提下,这操作完全是在挑战计算机设备的性能极端,这事在理论上根本没办法搞定,就连谷歌最后都只能选择砸钱堆服务器堆运维,才有了较好的性能。你又没服务器,又没人给你运维数据性能,这事怎么可能解决得了? 建议: 1.你应该选择你最关注的因素,比如读速度快,然后牺牲一下写数据,按这个模式,来做业务逻辑。 2.现在任何一款主流的分布式数据库,都做不到帮你把冷热数据均摊好,保证每台物理设备的性能平均。因为这个操作要涉及到经常的大规模的数据迁移,这个过程本身就会大幅度降低系统性能。因此,还不如你自己设计一个冷热数据记录器,再根据业务繁忙度,在闲时就像停服一样,重新分布冷热数据。这操作其实就是运维工作,你不去做这个工作,没办法把冷热数据高质量地均摊在不同物理设备上。 |
9
raynor2011 2020-02-05 07:25:55 +08:00 via Android
Hbase?
|
10
xautll 2020-02-05 08:57:23 +08:00
clickhouse 可以参考一下
|
11
sampeng 2020-02-05 09:06:31 +08:00 via iPhone
redis 完全够用…才百万级和 10 亿个元素…你也太小看 redis 了
|
12
defunct9 2020-02-05 10:44:03 +08:00 via iPhone
楼主最后用什么?
|
13
cabing 2020-02-05 10:48:28 +08:00
@dusu
算下成本。你的存储时 100G 吗? 如果觉得 redis 成本高的话, 单机的 io 又比较大,为啥不自己写个简单的 proxy 呢? 底层挂哪个存储都行,ssdb 或者 pika 或者直接用 rocksdb 做个存储也行。 |
17
wingyiu 2020-02-05 13:13:14 +08:00
redis 分片方案呗
|
18
dusu OP @laminux29 大佬说的是,问题描述确实有些矛盾,其实也是想请教一下在这个场景下,大家会用的一些低成本高收益的方案。
|
19
dusu OP @cabing 自己做 proxy 其实也尝试过 单机问题不大。但是涉及到「分布式」这块一致性和稳定性比较难彻底解决。遂放弃。
|
20
cabing 2020-02-05 13:23:38 +08:00
@dusu
分布式的 meta,使用 consul 或者 etcd 存下 meta 信息。 比较简单方案:做个一致性 hash,然后每个 node 都自己做个简单的拷贝方案,分布式存储存下 meta,这个最简单啊 需要改造,获取数据时做个 proxy 改造 |
21
luozic 2020-02-05 13:30:27 +08:00 via iPhone
是在云里面还是物理机器? 物理机器可以去看看 dpdk 这种方案,不过想要低成本的条件的话,最好根据具体的需求特征定制一下 proxy 层,存储层基本现在开源的 rocksdb 系的基本可以直接用。 通用的肯定不是特定场景下的成本最低方案。
|
22
justfly 2020-02-05 13:40:11 +08:00
直接尝试 redis cluster 吧。
我算了一下你的 value,大概 30 个字节,10 亿级别占用大概不到 30G 内存空间,留 5 倍的扩展空间和 value 外额外空间,redis 集群使用 10 个以内的节点够用了。 |
24
wangyzj 2020-02-05 20:36:35 +08:00
redis 啊
又不是不够用 再就得看业务场景和其它功能了 |
25
aliipay 2020-02-06 12:14:43 +08:00
val 搞什么 string,直接用 byte 定义
机器名:2Byte 最高支持 65536 台,如果不超过 128 个节点可以设为 1B,高 1 位保留扩展性 文件:crcr32 只要 4Byte 文件起始: 不知道具体范围,假设 4GB 内, 就是 4Byte. 如果存在小数值偏多,可以考虑 utf8 编码 文件长度:同上 所以总长度在 14B 左右,目测能少掉一半量 |