大数据量下的精确统计解决方案

2021-05-09 12:58:52 +08:00
 xiaofan2

目前我们面临的一个问题是每天我们跟资金相关的交易记录大概在 2T 左右,我们需要每日将这些信息进行统计然后给财务入账。目前采取的方式是将 mysql 的数据同步到 hive,然后从 hive 出数统计。但是在这个过程中 hive 可能存在数据丢失的情况,想问问大家行业内对这种大数据量的精确统计有没有什么解决方案?

2903 次点击
所在节点    Java
21 条回复
liprais
2021-05-09 13:15:46 +08:00
为啥 hive 会丢数
ipwx
2021-05-09 13:29:52 +08:00
2T? 硬盘读取速度在 100MB/s ~ 300MB/s 这个量级,扫一遍不到 1 分钟?实在不行原始数据弄成某种自有格式,然后写个程序扫一遍?
limbo0
2021-05-09 13:30:49 +08:00
最好多重方式进行验证, 保证一致
hive 为啥会丢失?
cxxlxx
2021-05-09 13:42:31 +08:00
@ipwx 请问是怎么的出 2t 扫描一编不到一分钟的?
makdon
2021-05-09 13:54:29 +08:00
@cxxlxx 应该是直接算的硬盘连续读写速度吧
但是为啥 hive 会丢数?
ipwx
2021-05-09 14:46:36 +08:00
@cxxlxx ummm 不好意思脑子秀逗了。20×1000s,大概是 5 个小时?
crclz
2021-05-09 16:38:39 +08:00
解决数据丢失:
方案一:借助数字 ID 的连续性。这个很好理解吧。如果 id 不是连续的,或者不是数字,请看方案 2.
方案二:只需要合理设计接口即可。具体见下面的例子。
方案三:使用 outbox pattern (交易记录增加一个字段“是否已同步”),需要借助最少一次送达的消息队列。https://microservices.io/patterns/data/transactional-outbox.html

方案 1 和 2 非常类似,属于数据接收方主动。方案 3 属于数据持有方主动。

---
举一个方案 2 的具体例子:

(先假设 id 的大小关系和时间的大小关系一致,或者说后插入的数据 id 大)

数据持有方这样设计请求接口:
GET /records?start=1001&count=500
response: { data: [...], hasNext: True }

这样设计的好处:
1. 批量操作(参数 count ),效率损失少。
2. 不会错过数据。接收方每次查询时,只需要将 start 设为自己数据库里面最后一条 id 即可。

注意:对于数据发送方是分布式数据库例如 mongodb,为了防止“后插入的数据 id 大”这一假设被打破,应当合理设置 read concern 。

---

具体是方案 2 还是方案 3,就见仁见智了。我个人认为方案 2 灵活性强,学习成本小,利于团队间合作。

性能方面的建议:
削峰。同步数据的工作分散到每一个小时,而不是每天结束时做。
Mohanson
2021-05-09 17:17:33 +08:00
没法想象一天 2T 的数据 + mysql 组合
Lemeng
2021-05-09 17:38:15 +08:00
丢数据,是有原因的吧,还有 2T 每天?
wmhack
2021-05-09 17:39:18 +08:00
可以写一个补数据的程序,在数据跑完之后,去 hive 当中查询缺失了哪些数据,然后从 mysql 当中拉取这部分丢失了的数据,再写入 hive
hallDrawnel
2021-05-09 18:38:48 +08:00
2T 是不是记录了太多不相关的数据?可以减少数据量吗?
xuanbg
2021-05-09 19:00:16 +08:00
1 天 2T 数据,最省钱省力的解决方案绝对是花钱请人搞而不是在这里发帖问。
ch2
2021-05-09 19:39:13 +08:00
把数据写到 clickhouse 里,2T 不是问题
akira
2021-05-09 20:00:14 +08:00
@xuanbg 应该是找什么人 也不知道去哪找,才来发帖的吧

同样不知道应该找什么人的路过。。。
ijk0
2021-05-09 20:39:37 +08:00
先找到 hive 丢数的原因吧(如果真的是 hive 的锅)
muzuiget
2021-05-10 01:18:50 +08:00
一天 2T 数据,这种级别,请个行业专家吧。
xiaofan2
2021-05-10 09:24:55 +08:00
@crclz 感谢您的回答。首先我们的 id 目前是不是连续的,虽然可以切换到 snowflake id 生成器,但是由于对这个算法进行了一些优化,比如会提前批量生成一批 id,所以只能保证趋势递增,而不能保证连续单调按时间递增,所以您说的一盒二实现起来有点困难。 对于方法三的话,由于对表进行更新的话会涉及到线上业务,有点困难
xiaofan2
2021-05-10 09:37:24 +08:00
@ch2 mysql 同步到 clickHouse 能保证数据不丢吗
weizhen199
2021-05-10 13:36:03 +08:00
一天 2T 数据,还是请人或者花钱找人吧。
精准统计 hive 还是太难为他了。多半你们也是开源自己搭的吧
crclz
2021-05-10 14:56:13 +08:00
@xiaofan2 不一定是 ID,时间戳字段也行。另外时间戳可能无法保证最新数据的插入顺序,但是一段时间之前(例如 10 分钟)的数据的顺序是稳定的。

对于插入顺序的保证:我去调研了一下,单机的可以保证(例如 MySQL AutoIncrease ),但是分布式的不能保证(例如 mongo )。此时一个解决方案是上文所说的(同步一段时间之前的数据),另一个解决方案是使用能够保证插入顺序的消息队列服务,例如 kafka 。

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

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

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

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

© 2021 V2EX