Kir*_*lla 6 mysql architecture counter distributed advertisement-server
我有一些后端服务器位于两个不同的数据中心(美国和欧洲).这些服务器只是在提供广告CPM.
除此之外,我还有大而肥的主MySQL服务器,为广告客户的广告系列提供资金余额.同样,所有广告系列都在提供CPM.
对于任何后端提供的每次展示,我都必须根据展示价格减少广告系列的余额.
例如,每次展示的价格为1美分.后端A已经实现了50次展示,并将减少50美分的资金余额.支持B已经提供了30次印象,它将减少30美分的货币余额.
所以,我看到的主要问题是:
后端每秒提供大约2-3K的展示次数.因此,在MySQL中飞行中减少货币余额并不是一个好主意.
后端位于美国和欧盟数据中心.MySQL主服务器位于美国.网络延迟可能是一个问题[欧盟后端] < - > [美国大师]
我看到可能的解决方案:
使用Cassandra分布式计数存储.我会尽可能地意识到这个解决方案.
通过后端保留部分资金.例如,后端A连接到master并尝试保留$ 1.由于$ 1被保留并本地存储在后端(Redis例如本地),因此以光速递减它是没有问题的.我看到的主要问题是如果后端从交付方案中被禁用(从平衡器"断开"),则从后端返回主服务器.无论如何,它似乎是一个非常好的解决方案,并将允许留在当前的技术堆栈.
有什么建议?
UPD:一个重要的补充.提供高精度的广告展示并不是那么重要.我们可以提供超出要求的展示次数,但绝不会少.
如何而不是减少余额,您保留每个后端所有报告工作的日志,然后在需要时通过从广告系列帐户中减去所有报告的工作总和来计算余额?
表:
campaign (campaign_id, budget, ...)
impressions (campaign_id, backend_id, count, ...)
Run Code Online (Sandbox Code Playgroud)
报告工作:
INSERT INTO impressions VALUES ($campaign_id, $backend_id, $served_impressions);
Run Code Online (Sandbox Code Playgroud)
仅在必要时计算广告系列的余额:
SELECT campaign.budget - impressions.count * $impression_price AS balance
FROM campaign INNER JOIN impressions USING (campaign_id);
Run Code Online (Sandbox Code Playgroud)
这可能是最经典的广告服务/印象计数问题。您基本上是在尝试平衡几个目标:
这很棘手,因为您不一定知道给定位置有多少展示次数(因为它取决于流量),如果您使用每次点击费用而不是每千次展示费用,情况会变得更加棘手,因为您随后引入了另一个不可知的变量点击率。
对此没有单一的“正确”模式,但我通过多年的咨询看到成功的是:
将后端数据库视为您的权威存储。根据需要按客户对其进行分区,以支持您的可扩展性和容错性目标(将可能的中断限制在一小部分客户范围内)。数据库知道您有一个广告插入订单,例如在 7 天内有 1000 次展示。它会定期更新(几分钟到几小时)以反映剩余库存和一些基本统计信息,以便在缓存丢失的情况下引导缓存,例如实际情况
不必担心广告服务器级别的资金余额。仅处理展示次数、费率和目标。事后通过日志记录和离线处理将其结算为货币余额。
从一个非常轻量且快速的缓存(靠近网络服务器)提供广告库存,该缓存缓存剩余展示次数和插入订单的目标服务速度,并计算实际的服务速度。
使用相关数据记录所有投放的展示次数。
定期收集服务速度并将其推回数据库。
定期收集日志并计算实际服务的库存并将其推送回数据库。(由于中断、DoS、垃圾邮件等,您可能需要根据日志重新计算)