千万级数据 10 毫秒以内的简单查询 有什么最佳实践? - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
woduzibue
V2EX    数据库

千万级数据 10 毫秒以内的简单查询 有什么最佳实践?

  •  
  •   woduzibue 2024-07-30 10:43:17 +08:00 via iPhone 6408 次点击
    这是一个创建于 504 天前的主题,其中的信息可能已经有所发展或是发生改变。
    千万级别的数据量,简单查询,要求响应时间 10ms 左右能做到么?或者 50ms 以内
    关键字是一些汉字组合 查处相关的信息 ,目前只需要考虑查询
    请教各位大佬 现在都有哪些成熟的方案
    我了解下来最方便的还是 redis 加 mysql
    es 不太清楚行不行

    各位大佬支支招
    第 1 条附言    2024-07-30 11:33:29 +08:00
    数据 举个例子 就是 ,所有的地标(商店、宾馆)名称和这些地标的类型、介绍之类的信息
    要求就是 输入名称 快速返回是不是一个 地标 和是什么类型的
    第 2 条附言    2024-07-30 14:07:05 +08:00
    再延伸一下 上述情况下 亿级数据量 下简单查询
    应该用什么方案
    考虑到以后数据量增大的情况下该如何挑选方案
    42 条回复    2024-08-01 16:29:04 +08:00
    dzdh
        1
    dzdh  
       2024-07-30 10:50:45 +08:00   1
    manticoresearch

    zincsearch

    meilisearch (内存成本高)

    sphinxsearch (已闭源能免费下载)


    tantivy 使用难度高
    woduzibue
        2
    woduzibue  
    OP
       2024-07-30 10:55:26 +08:00 via iPhone
    @dzdh 感谢大佬 我去查查看看
    whileFalse
        3
    whileFalse  
       2024-07-30 11:10:15 +08:00 via Android   1
    你倒是说是什么样的数据啊
    shimada666
        4
    shimada666  
       2024-07-30 11:29:29 +08:00   2
    单机 clickhouse 秒了
    nice2cu
        5
    nice2cu  
       2024-07-30 11:31:19 +08:00   1
    es 可以
    woduzibue
        6
    woduzibue  
    OP
       2024-07-30 11:33:00 +08:00 via iPhone
    @whileFalse 数据 举个例子 就是 ,所有的地标(商店、宾馆)名称和这些地标的类型、介绍之类的信息
    要求就是 输入名称 快速返回是不是一个 地标 和是什么类型的
    ychost
        7
    ychost  
       2024-07-30 11:33:34 +08:00   1
    阿里云 TableStore ,目前 10 亿数据,大概 10ms 返回
    woduzibue
        8
    woduzibue  
    OP
       2024-07-30 11:37:19 +08:00 via iPhone
    @ychost 这个看下来好贵呀 不知道是不是我看的价格不对
    RandomJoke
        9
    RandomJoke  
       2024-07-30 11:40:35 +08:00   1
    千万级别 ES 应该随意应付
    BiChengfei
        10
    BiChengfei  
       2024-07-30 11:45:35 +08:00   1
    ( type ,name ),需要根据 name 全文索引。MySQL InnoDB + 固态就够了吧,千万数据真的很小,如果 name 是精确搜索,就唯一索引,模糊搜索就全文索引。不行就用 Memory 引擎
    Nich0la5
        11
    Nich0la5  
       2024-07-30 11:52:53 +08:00   1
    索引建的没问题的话 大部分数据库都能满足
    decken
        12
    decken  
       2024-07-30 11:53:25 +08:00   1
    mysql 可以了 机器好一点
    woduzibue
        13
    woduzibue  
    OP
       2024-07-30 11:57:28 +08:00 via iPhone
    @BiChengfi 嗯 需要精确搜索
    woduzibue
        14
    woduzibue  
    OP
       2024-07-30 11:58:22 +08:00 via iPhone
    @decken
    @Nich0la5 之前知识用过 mysql 做一些业务,没有具体关注过耗时这么低的场景 感谢感谢
    mark2025
        15
    mark2025  
       2024-07-30 12:06:43 +08:00   1
    XepMCWEKZ76L695l
        16
    XepMCWEKZ76L695l  
       2024-07-30 12:14:39 +08:00   1
    mysql 足以
    yjhatfdu2
        17
    yjhatfdu2  
       2024-07-30 12:54:52 +08:00   1
    这点数据,模糊搜索直接 pg 用 bigm_gin 索引秒了
    hefish
        18
    hefish  
       2024-07-30 13:32:31 +08:00   1
    直接存 ssd 上搞个散列表就行了。
    wxf666
        19
    wxf666  
       2024-07-30 13:49:08 +08:00   1
    这点数据,即使是在性能弱鸡的手机端,进行全文搜索,不是最简单的 1MB 的 SQLite ,都能解决的吗?


    [《微信全文搜索耗时降 94%?我们用了这种方案》]( https://cloud.tencent.com/developer/article/2220615 ) 里说:

    > 一个包含 100w 条中文内容、每条长度 100 汉字的 FTS5 的表查询三个词,optimize 状态下耗时 2.9ms

    > 100w 条内容每次写入 100 条的情况下,按照 WCDB 的方案执行 merge ,耗时在 10s 内。
    Kinnice
        20
    Kinnice  
       2024-07-30 13:52:58 +08:00   1
    ck 秒了
    es 秒了
    mysql 秒了
    pg 秒了

    总结:千万量级不算大,业务也不复杂,做好索引即可
    singer
        21
    singer  
       2024-07-30 13:53:24 +08:00   1
    redis + mysql 稳了
    zagfai
        22
    zagfai  
       2024-07-30 14:06:52 +08:00   1
    字典树
    woduzibue
        23
    woduzibue  
    OP
       2024-07-30 14:08:42 +08:00 via iPhone
    @Kinnice 那亿级别的 哪种方案好扩展数据量 也只是简单查询
    Granado
        24
    Granado  
       2024-07-30 14:29:55 +08:00   1
    我看了下我线上库,1.1 亿数据,走索引查单条数据室 5ms 左右,mysql 在物理机上,物理机配置较高。
    7911364440
        25
    7911364440  
       2024-07-30 14:30:20 +08:00   1
    mysql 主从,主表 innodb 只写 从表 memory 只读
    woduzibue
        26
    woduzibue  
    OP
       2024-07-30 14:34:45 +08:00 via iPhone
    @7911364440 嗯嗯 写可能就停机批量写,大部分场景读
    yjhatfdu2
        27
    yjhatfdu2  
       2024-07-30 14:41:23 +08:00   1
    @woduzibue 你的简单查询是等值查询还是 like 匹配?
    Kinnice
        28
    Kinnice  
       2024-07-30 14:49:14 +08:00   1
    @woduzibue #23 ck 和 es
    csbde
        29
    csbde  
       2024-07-30 15:06:21 +08:00   1
    单机 clickhouse 轻松应对,我们数十亿数据的高并发查询都轻松拿捏,在线写也轻松,就是删除比较麻烦
    woduzibue
        30
    woduzibue  
    OP
       2024-07-30 15:21:53 +08:00 via iPhone
    @yjhatfdu2 暂时就等值查询,后续可能会考虑 like 但暂时是没这个打算

    @Kinnice 好的 感谢大佬
    @csbde 好的感谢大佬
    brybeZhang
        31
    brybeZhang  
       2024-07-30 15:32:16 +08:00   1
    @Nich0la5 按照题主的需求 , %name%, 这样索引就失效了吧, 就上 es 吧,es 是开源的, 就 MySQL 加 es , 业界成熟方案, 外包 公司 大规模使用的
    andyxq
        32
    andyxq  
       2024-07-30 15:39:34 +08:00   1
    前段时间测试 clickhouse, 目前库里 530 亿条数据查询蛮轻松
    singer
        33
    singer  
       2024-07-30 16:06:46 +08:00   2
    我来讲一个方案给楼主点思路。

    我在广告方面做过一些项目,热点数据量在几亿条,存储占用四五 T ,需要秒级别延迟下的数据检索。
    开始我们用了 starrocks ,但 starrocks 在广告场景下密集写入数据后索性能极差(这里不是点 starrocks ,只是我们在用这个。实际上各种号称大数据搜索的都有这种问题)。线上事故不断,资损动不动就是几十万,巅峰时期 3 天 4 个线上事故。
    后来我们想了一个办法,搜索的字段和内容是固定的。我们动用了两套数据库,一个是常规的大容量存储,保证原始数据不丢失(这块我们不用于线上查询,偶尔 T+1 检索,目的是保证数据可以用来恢复业务需要的数据以及数分团队抽数分析),另一个是 Redis ,通过 ETL 方式将数据通过规则(规则是可配置的,比如“今天是星期天”,分词后就是“今天”,“星期天”)写入 Redis 作为索引。

    * 检索:检索的时候仅查询 Redis ,从 Redis 中查到原始数据的索引,再去获取需要的数据

    * 数据重刷:规则是固定的,随着业务的发展,规则需要变更。分词变更成“今天是星期天”要分词成“今天”,“2024/07/30”,“星期天”,“2024/08/04”,这个时候只能重刷数据。刷数就会导致未知风险,为了保证线上可以无感切换,我们还准备了两条数据链路,刷数链路清完数据开始从大容量存储里捞数据,重建影响范围内的数据。刷完后切换查询数据源。再把原来的数据链路重复上面的步骤。

    以上一把操作后,我们的热点数据存储从之前的几 T 变成了百 G 。热点数据的数据量上的降低让我们系统 SLA 从 95%提升到 99.9%以上,接口耗时从 200 ~ 300ms 变成了 5ms 。

    -----
    ES 对于千万级别的数据用起来还算顺手,但数据量上去后 C 端接口抖动真的难以优化。如果有预期数据量在短期有数十倍增长就不必折腾了。B 端业务可以上,B 端接口 10ms 与 200ms 的感知不明显。
    woduzibue
        34
    woduzibue  
    OP
       2024-07-30 16:33:07 +08:00 via iPhone
    @brybeZhang 嗯 短期内不会有模糊查询的需要,支持精确查找就行,感谢大佬

    @andyxq 感谢大佬

    @singer 感谢大佬分享 我的场景比你这个要简单一点 不需要规则 非常感谢
    magic7758
        35
    magic7758  
       2024-07-30 18:10:08 +08:00
    @csbde ck 高并发?你这就是简单的索引键少字段点差询?
    Jooooooooo
        36
    Jooooooooo  
       2024-07-30 19:00:42 +08:00   1
    10ms 不可能,光是消耗在网络传输的时间就比这个长

    唯一可行的放在机器内存里
    nx6Ta67v2A43frV2
        37
    nx6Ta67v2A43frV2  
       2024-07-30 19:08:09 +08:00   1
    看业务场景。
    如果是静态元数据,那么,楼上说的方法都可行。
    如果数据涉及到交易,那么,最好用关系型数据库。

    举个例子:
    我之前做过 1 个机票垂直搜索系统,在搜索系统中,涉及到 2 类数据。

    第 1 类是静态元数据,比如:航司、城市、机场。
    这类数据只用于对外展示,不影响业务流程走向。
    通过中心式缓存,或者当作静态配置,都可以解决。
    我们是采用静态配置,基于长轮询做了个增量更新协议。
    原因是,我们的查询频次和范围非常高。

    第 2 类是交易数据,比如:各个代理商的报价政策。
    这些数据决定了机票价格,代理商会高频调价,直接影响机票金额。
    这种一般是采用分库分表,我们分了 1024 个短表,然后并发查。
    每个 sql 语句 select 字段不超过 5 个字段,where 条件不超过 3 个字段,全部走索引。
    通过中间件实现报价源和搜索系统中间的数据同步,节点间采取半同步复制。
    最终,基本能够达到你提到的性能要求,能够轻松支持亿级数据,代理商改价后,搜索服务秒级感知。
    sketcherly
        38
    sketcherly  
       2024-07-30 19:53:05 +08:00   1
    简单查询,走索引的话,直接查 MySQL 表问题不大吧
    woduzibue
        39
    woduzibue  
    OP
       2024-07-30 1:21:19 +08:00 via iPhone
    @Jooooooooo 50ms 以内也能接受

    @kong0bbs 不涉及更新和交易

    @sketcherly 嗯 准备先试试 之前没接触过这么多体量的数据
    Desdemor
        40
    Desdemor  
       2024-07-31 10:15:50 +08:00   1
    目前用的 ck,我们单表数据过亿了,也很快
    joetao123
        41
    joetao123  
       2024-07-31 10:39:26 +08:00   1
    之前做健康码的时候,4000 多万人口的数据使用 ES 进行存储和查询,就是简单的通过身份证号查询,使用 8 台 64G 内存 1TSSD 服务器,查询耗时在 1ms 左右。ES 级群也支持动态扩容/缩容, 操作起来也不难。
    encro
        42
    encro  
       2024-08-01 16:29:04 +08:00
    @joetao123

    随便给个数据库,都是 1ms 。。。。而且只需要 2g4g 即可。
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     1170 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 28ms UTC 23:40 PVG 07:40 LAX 15:40 JFK 18:40
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86