具有实时余额更新的大批量交易的最佳做法

时间:2017-02-25 20:02:39

标签: php mysql hadoop apache-kudu bigdata

我目前有一个MySQL数据库,处理大量的交易。为了简单起见,它是一个实时的动作(点击和其他事件)数据流。结构是这样的,用户属于子关联公司,子关联公司属于关联公司。

我需要保持点击的平衡。为了简单起见,我们说我需要为每个用户,子会员和联盟会员增加点击余额1(根据事件实际上有更多处理)。目前我非常简单地做 - 一旦我收到事件,我在PHP中进行顺序查询 - 我读取用户的余额,递增1并存储新值,然后我读取子会员的余额,增量和写等等。

用户的余额对我来说是最重要的衡量标准,所以我希望尽可能保持实时。 sub-aff和affiliate级别的其他指标不太重要,但它们与实时越接近越好,但我认为5分钟的延迟可能没问题。

随着项目的发展,它已经成为瓶颈,我现在正在寻找替代方案 - 如何重新设计余额的计算。我想确保新设计能够每天处理5000万个事件。对我来说,不要丢失单个事件也很重要,我实际上将每个更改周期包装在sql事务中的点击余额中。

我正在考虑的一些事情:

1 - 创建一个cron作业,该作业将不会实时更新子会员级别和会员级别的余额,让我们每隔5分钟说一次。

2 - 使用存储过程将数字运算和平衡更新移动到数据库本身。我正在考虑添加一个单独的数据库,也许Postgress会更适合这份工作吗?我试图看看是否有严重的性能提升,但互联网似乎对这一主题存在分歧。

3 - 将这个特定的数据流移动到带有镶木地板(或Apache Kudu?)的hadoop之类的东西,并在需要时添加更多服务器。

4 - 对现有数据库进行分片,基本上为每个分支机构添加一个单独的数据库服务器。

是否有一些针对此类任务的最佳实践/技术或一些我可以做的明显事情?任何帮助都非常感谢!

4 个答案:

答案 0 :(得分:0)

如果我是你,我会实施Redis内存存储,并增加你的指标。它非常快速可靠。您也可以从此DB中读取。创建cron作业,将这些数据保存到MySQL DB中。

答案 1 :(得分:0)

您的网络层是否在收到数字时进行数字处理&处理HTTP请求?如果是这样,您要做的第一件事就是将其移至工作队列并异步处理这些事件。我相信你在第3项中暗示了这一点。

有很多解决方案,选择一个的范围超出了本答案的范围,但需要考虑一些包:

  • 的Gearman / PHP
  • Sidekiq /红宝石
  • 亚马逊SQS
  • 的RabbitMQ
  • NSQ

...等...

在存储方面,它实际上取决于您要实现的目标,快速读取,快速写入,批量读取,分片/分发,高可用性......每个方向的答案都指向不同的方向

答案 2 :(得分:0)

我对高速摄取的建议是here。在您的情况下,我会在它描述的乒乓球表中收集原始信息,然后让另一个任务汇总该表以执行计数器的质量UPDATEs。当流量突然增加时,它会变得更有效率,从而不会过度使用。

点击余额(和“类似计数”)应位于与所有相关数据分开的表格中。这有助于避免干扰系统中的其他活动。如果您拥有的数据多于缓冲区中可缓存的数据,则可能会提高余额的可缓存性。

请注意,我的设计不包含cron作业(除了“keep-alive”之外)。它处理一个表,翻转表,然后循环回处理 - 尽可能快。

答案 3 :(得分:-1)

这听起来像是Clustrix的绝佳候选者,这是MySQL的替代品。它们执行类似分片的操作,但不是将数据放在单独的数据库中,而是将它拆分并在同一个数据库集群中的节点之间进行复制。他们称之为切片,数据库会自动为您完成。它对开发人员来说是透明的。它上面有一个good performance paper显示它是如何完成的,但缺点是它是一个横向扩展的OTLP数据库,它恰好能够吸收对实时数据进行疯狂的分析处理。