【发布时间】:2020-12-17 15:12:02
【问题描述】:
我多年来一直在开发一个高流量的广告服务平台,使用一个主-主 Maria 数据库集群,前面有一个 HAProxy 来平衡关系数据查询(读取查询到所有服务器,但只写入为一,以防止服务器不同步)。我所说的关系数据是指活动设置、用户详细信息、付款等内容。我也在使用 Redis 来缓存一些不太动态的 MySQL 信息,但我相信有很多机会可以更好地利用它,因为一旦流量增加,我就会经常遇到瓶颈,例如:
- 与 MySQL 的连接过多
- 死锁(可能是因为当主服务器过载时,多台服务器开始写入)。
我的目标是将尽可能多的写入从 MySQL 转移到 Redis,但我很难根据存储在 Redis 中的计数/预算来过滤 MySQL 数据,尤其是在传统 JOIN 的地方用过。
这样的 MySQL 查询的简化示例会在用户预算内获得最高出价的广告系列:
SELECT campaigns.id, campaigns.url FROM campaigns
JOIN users ON campaigns.user_id = users.id
ORDER BY LEAST(users.credits, campaigns.bid) DESC
LIMIT 1;
在该广告系列获得点击后,需要立即削减预算。当然,减少 MySQL 中的 credits 是微不足道的,但是一旦用户开始每秒发送多次点击,问题就开始出现(主要是集群中的死锁或达到最大连接数)。
在 Redis 中应用信用减少是首选,但我在连接 Redis 中的一堆信用记录之间的点以及基于此过滤和排序 MySQL 记录时遇到了麻烦。
什么是解决这个问题的好方法,可以让我尽可能少地接触 MySQL?或者也许我需要采取完全不同的方法来实现这一点。
任何建议或链接将不胜感激。
【问题讨论】:
-
避免写入连接问题的一种可能方法是写入 Redis 流(或 Kafka)之类的东西,然后使用消费者从主题中读取并执行批量插入 MySQL 写入器。然后你仍然可以使用 MySQL 进行读取。不同之处在于,从插入记录到消费者将信息放入 MySQL 之间会有延迟。您可以从一个表开始,然后根据需要添加更多表以减少连接超时。
-
这是我从未想过的,但听起来很有希望。这样的策略我应该期待什么样的延迟?我有一种感觉,这可以以近乎实时的方式实现。我是不是太乐观了?
-
@user1782560 这将是接近实时的,延迟将主要在消费者端,因此您可以期望消费者应该能够在 1-2 秒内写入,这也取决于 Kafka或 Redis 流延迟。像 Redis Stream 这样的系统会为您提供 Ms 延迟,但 DB 写入可能需要一些时间。明智的做法是等待 N 条记录而不是写入一条记录,如果没有足够的记录怎么办,因此您应该结合使用计时器和批量大小。