1

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

我需要保持点击的平衡。为简单起见,假设我需要将每个用户、子关联公司和关联公司的点击余额增加 1(实际上取决于事件的处理更多)。目前我做的非常简单——一旦我收到事件,我会在 PHP 中进行顺序查询——我读取用户的余额,加一并存储新值,然后我读取子附属公司的余额,递增并写入, ETC。

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

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

我正在考虑的一些事情:

1 - 创建一个 cron 作业,它将不实时更新子附属公司和附属公司级别的余额,假设每 5 分钟一次。

2 - 使用存储过程将数字处理和余额更新移动到数据库本身。我正在考虑添加一个单独的数据库,也许 Postgress 会更适合这项工作?我试图看看是否有严重的性能改进,但互联网似乎在这个话题上存在分歧。

3 - 将这个特定的数据流移动到带有 parquet(或 Apache Kudu?)的 hadoop 之类的东西,如果需要,只需添加更多服务器。

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

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

4

4 回答 4

0

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

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

  • 齿轮人/PHP
  • Sidekiq/红宝石
  • 亚马逊 SQS
  • 兔MQ
  • NSQ

...ETC...

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

于 2017-02-25T20:09:06.537 回答
0

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

于 2017-02-25T20:06:03.917 回答
0

我对高速摄取的建议在这里。在你的情况下,我会在它描述的乒乓球表中收集原始信息,然后让另一个任务总结表来做大量UPDATEs的计数器。当流量激增时,它会变得更有效率,从而不会倒下。

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

请注意,我的设计不包括 cron 作业(可能作为“保持活动”除外)。它处理一个表,翻转表,然后循环返回处理——尽可能快。

于 2017-02-25T20:58:12.943 回答
-1

这听起来像是Clustrix的绝佳候选者,它是 MySQL 的替代品。他们执行分片之类的操作,但不是将数据放在单独的数据库中,而是将其拆分并在同一数据库集群中的节点之间复制。他们称之为切片,数据库会自动为您完成。它对开发人员是透明的。有一篇很好的性能论文展示了它是如何完成的,但不足之处在于它是一个横向扩展的 OTLP DB,恰好也能够吸收对实时数据的大量分析处理。

于 2017-03-08T00:01:20.297 回答