数据库设计 - 分槽计数器模式

📢 数字海洋中的航标:高并发计数秘密

在业务中我们或许会遇到计数需求的业务,比如页面浏览、下载等业务。传统的计数方法,如直接在数据库中更新一个计数器,虽然简单直接,但在面对成千上万的并发请求时,却容易成为性能瓶颈。这是因为频繁的更新操作会导致数据库行锁争用,增加查询耗时,甚至可能引发死锁,从而影响整个系统的性能和稳定性。

这时候分槽计数器就可以发挥很好作用了。它不仅优雅地解决了高并发下的计数问题,还为数据库操作的优化提供了新的视角

🕊️ 魔法实验室:实战妙用

create table `slotted_events` (
  `id` int(11) not null auto_increment,
  `browsing_type` int(11) not null,
  `item_id` int(11) not null,
  `slot` int(11) not null default '0',
  `s_count` int(11) default null,
  primary key (`id`),
  unique key `idx_slotted_counters_bis` (`browsing_type`,`item_id`,`slot`)
) engine=innodb;

比如browsing_type为浏览类型,item_id为商品idslot则是我们引入的槽,s_count则为次数。

现在当用户浏览后,我们可以不用通过update的方式增加次数(前面提到的高并发场景下的行锁等待),而是直接写入数据。

insert into slotted_events(browsing_type, item_id, slot, s_count)
values (1, 100013, rand() * 100, 1)
on duplicate key update s_count = s_count + 1;

其中on duplicate key update的作用是处理碰到的重复键情况。如果browsing_typeitem_idslot产生重复数据,则不是插入新行,而是更新这个已存在的行。更新操作是将 s_count字段的值增加 1(即s_count = s_count + 1`)。每次事件发生时,随机选择一个槽位进行计数,如果这个槽位已经存在,则增加其计数值。这样做可以有效地分散数据库的写入操作,减少对单一数据行的频繁访问,从而提高数据库的性能和并发处理能力。

由于我们通过随机数分配槽位,但是随机数的区间范围不是很大,因此sum一般不会造成性能瓶颈。

-- browsing_type为1的商品100013的浏览次数
select
    sum(s_count)
from
    slotted_events
where
    browsing_type = 1
    and item_id = 100013;
    

✈️ 总结:要不要关注一下我

我们可以看到,分槽计数器模式在处理高并发计数需求时展现出显著的优势。它不仅优化了数据库的性能,减少了锁争用和死锁的风险,还提供了一种灵活且高效的方式来处理大量数据的实时更新。

这种模式特别适用于需要快速响应用户行为的应用场景,如商品浏览、社交媒体的互动计数,或是内容平台的下载和观看次数统计。通过将计数操作分散到多个槽位,我们能够在保持数据准确性的同时,显著提高系统的并发处理能力。

当然,任何技术方案都不是万能的。在实际应用分槽计数器模式时,我们需要根据具体业务的特点和数据量来调整槽位的数量和分布,以达到最佳的性能平衡。此外,对于数据的最终汇总和分析,也需要考虑合适的策略来确保效率和准确性。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值