徕枫科技面试

有 100 亿条交易数据,每秒还有新增1000条,主要字段有from_address,to_address,amount,timestamp,请设计一个方案,使用户使用API查询用户交易数和交易金额总和的时间<1s,可以接受 10s的延时

对于这样一个大数据量和高并发查询的场景,我们可以使用 分布式存储分布式缓存 的方案来优化 API 查询,确保在 1 秒以内返回结果。以下是一个高效的方案设计:

1. 数据存储

将交易数据存储在分布式数据库中,比如 ClickHouseBigtable。这些数据库能够处理大规模的数据,并且在聚合查询上有较高的性能。需要确保以下几点:

  • 分区设计:将数据按 from_addressto_address 进行分区,方便快速查找某个地址的交易。
  • 索引:为 from_addressto_address 字段添加索引,以加快查询速度。
  • 压缩:在数据库层面设置数据压缩,降低存储成本,并减少读取数据时的磁盘 IO。

2. 缓存设计

由于允许数据查询有 10 秒的延时,可以使用缓存来提高查询速度。考虑使用 RedisMemcached 来存储聚合数据。

  • 数据结构:为每个地址存储一个统计数据对象,包括交易总数和交易总金额。
  • 缓存更新频率:每隔 10 秒进行一次批量更新。可以通过数据库的定时任务或流式处理框架(如 Kafka + Flink)来定期计算增量数据,并更新缓存。

3. 流式处理

新交易数据的持续增加可以通过流式处理系统(如 Apache FlinkApache Kafka Streams)来处理:

  • 增量聚合:流式处理系统负责实时计算增量数据,并在缓存中更新各个地址的交易总数和总金额。
  • 延迟容忍:可以将计算的结果存储在 Redis 中,允许延迟 10 秒更新。

4. API 查询

API 查询某个地址的交易数和交易金额时的流程如下:

  1. 读取缓存:首先在 Redis 缓存中查找该地址的交易总数和交易总金额。
  2. 回退查询:若缓存中未命中该地址数据,可以回退到数据库进行查询,并将结果写入缓存。
  3. 异步更新缓存:设置一个异步任务,当数据库有新的数据时自动刷新缓存。

5. 具体实现细节

  • 批量更新缓存:可以使用 Flink 从数据库中提取增量数据,并将聚合后的结果写入缓存。
  • 分片机制:对于超高并发的查询,可以使用 Redis 分片集群,确保缓存查询的高可用性和负载均衡。
  • 负载均衡:将 API 部署在多个服务器上,通过负载均衡分发请求,确保高并发情况下的性能。

通过以上方案,可以实现低延时的交易查询,并且即使数据量持续增加,系统也可以通过分布式架构保持性能。

数据库使用mysql如何实现

如果必须使用 MySQL 来处理这类大数据量和高并发的查询需求,可以采取以下优化方案,使查询性能满足 1 秒以内的响应时间要求。

方案概述

使用 MySQL 进行分区、索引优化,并通过定时批量汇总交易数据存储到 Redis 缓存中,从而加快 API 的查询速度。同时,采用分布式架构和异步更新缓存的方式来满足实时性和并发性要求。

1. 数据库设计与分区

由于 MySQL 不适合直接处理百亿级数据量的实时查询,可以采用 分表分区 来优化性能。

数据库分区策略

  • 按时间分区:可以按天或按月对交易表进行分区,借助 MySQL 的 PARTITION BY RANGE 功能,以 timestamp 字段进行分区,方便清理历史数据和加速查询。
  • 按地址分表:可以根据 from_addressto_address 将数据水平分表,比如按哈希的前缀将数据分散到多张表中,减少单表数据量。

2. 缓存设计

为提高查询性能,我们可以使用 Redis 缓存 存储每个地址的交易总数和总金额数据。

缓存结构

  • Key:交易地址(from_addressto_address)。
  • Value:包含交易总数和交易总金额的 JSON 对象,例如 {"count": 100, "total_amount": 500.25}

缓存更新

  • 每隔 10 秒使用 MySQL 的 增量更新批量统计 来计算最近新增的数据,将其合并到 Redis 缓存中。
  • 更新频率可以根据业务需求调整,确保 10 秒以内的延时容忍度。

3. 增量聚合方案

可以利用 定时任务消息队列 + 消费者 模式来计算并更新缓存:

  • 定时任务(例如,基于 CRON 定时任务):每 10 秒执行一次,将最近新增的交易数据聚合到 Redis。
  • 增量数据表:将每秒新增的 1000 条数据暂时存储到增量表 transactions_increment 中,定期聚合后转存到 Redis,并清理增量表。

4. API 查询逻辑

API 查询流程设计为:

  1. 从 Redis 读取缓存:直接从 Redis 查询目标地址的交易总数和交易总金额。
  2. 缓存未命中时的回退查询
    • 如果 Redis 中没有该地址的缓存,则从 MySQL 中查询。
    • 将查询结果写入 Redis,方便后续请求直接命中缓存。

方案优势

  • 延迟容忍:利用 Redis 缓存提高查询性能,满足 10 秒延迟容忍要求。
  • 分区分表:减小单表查询压力,优化 MySQL 的性能。
  • 增量聚合:减少 MySQL 的负载,仅聚合增量数据,降低计算压力。

通过上述方案,可以使 API 查询接口在 MySQL 上实现较高的性能,同时借助 Redis 缓存满足 1 秒以内的响应时间。

查询地址可能是 from_address,也可能是 to_address,如何分表能兼顾地址的快速查询

为了满足查询地址可能是 from_addressto_address 的需求,可以采用以下的分表和索引方案,以兼顾地址字段的快速查询。

方案 1: 双表存储方案

创建两张表,分别存储基于 from_addressto_address 的交易数据:

  • transactions_from:存储以 from_address 为主键的数据,用于按 from_address 查询的情况。
  • transactions_to:存储以 to_address 为主键的数据,用于按 to_address 查询的情况。

每当有新的交易数据插入时,向两张表插入相同的记录,但分别在不同的表中以 from_addressto_address 为主索引。这样可以减少在单张大表上查询两个不同字段带来的性能开销。

优点

  • 查询速度:可以在不同的表中使用合适的索引进行快速查找,适合查询 from_addressto_address
  • 写入速度可控:虽然每条交易记录要写入两次,但查询效率显著提升。

缺点

  • 数据冗余:数据量翻倍,占用更多的存储空间。
  • 维护复杂性:需保证两表的数据一致性,尤其是在更新和删除操作时。

方案 2: 单表联合索引方案

如果不希望数据冗余,仍然使用单表存储,但对 from_addressto_address 分别建立独立索引:

这种方案适合数据量不至于过大的情况下,通过分别建立 from_addressto_address 的索引来加快查询速度。查询某个地址的交易时,可以通过这两个索引分别查询。

优点

  • 无数据冗余:节省存储空间。
  • 维护方便:只需维护一张表,增删改操作简单。

缺点

  • 查询性能受限:在极大数据量情况下,两种查询压力集中在一张表上,查询效率不如双表方案。

方案 3: 基于分区+联合索引

可以结合 MySQL 分区联合索引,按时间分区并建立 from_addressto_address 的联合索引。

优点

  • 分区加速:按时间分区有助于查询近期数据时只扫描一部分分区,提高查询速度。
  • 节省存储:无冗余数据,节省存储空间。

缺点

  • 复杂性:分区维护、分区管理比较复杂,在数据量极大时,单表上两种不同字段查询效率仍不如双表方案。

方案选择

  • 双表方案(方案 1):适用于数据量大、读多写少的场景。
  • 联合索引方案(方案 2):适合数据量中等的场景,存储成本较低。
  • 分区+联合索引方案(方案 3):适合查询多为近期数据的场景,通过分区减少查询范围。

总体来看,如果追求高查询性能且存储空间允许,方案 1 更适合百亿级数据查询需求,保证查询速度在 1 秒以内。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 219,490评论 6 508
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,581评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 165,830评论 0 356
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,957评论 1 295
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,974评论 6 393
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,754评论 1 307
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,464评论 3 420
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,357评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,847评论 1 317
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,995评论 3 338
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,137评论 1 351
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,819评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,482评论 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,023评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,149评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,409评论 3 373
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,086评论 2 355

推荐阅读更多精彩内容