📢 数字海洋中的航标:高并发计数秘密
在业务中我们或许会遇到计数需求的业务,比如页面浏览、下载等业务。传统的计数方法,如直接在数据库中更新一个计数器,虽然简单直接,但在面对成千上万的并发请求时,却容易成为性能瓶颈。这是因为频繁的更新操作会导致数据库行锁争用,增加查询耗时,甚至可能引发死锁,从而影响整个系统的性能和稳定性。
这时候分槽计数器
就可以发挥很好作用了。它不仅优雅地解决了高并发下的计数问题,还为数据库操作的优化提供了新的视角
🕊️ 魔法实验室:实战妙用
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
为商品id
,slot
则是我们引入的槽,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_type,
item_id和
slot产生重复数据,则不是插入新行,而是更新这个已存在的行。更新操作是将
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;
✈️ 总结:要不要关注一下我
我们可以看到,分槽计数器模式在处理高并发计数需求时展现出显著的优势。它不仅优化了数据库的性能,减少了锁争用和死锁的风险,还提供了一种灵活且高效的方式来处理大量数据的实时更新。
这种模式特别适用于需要快速响应用户行为的应用场景,如商品浏览、社交媒体的互动计数,或是内容平台的下载和观看次数统计。通过将计数操作分散到多个槽位,我们能够在保持数据准确性的同时,显著提高系统的并发处理能力。
当然,任何技术方案都不是万能的。在实际应用分槽计数器模式时,我们需要根据具体业务的特点和数据量来调整槽位的数量和分布,以达到最佳的性能平衡。此外,对于数据的最终汇总和分析,也需要考虑合适的策略来确保效率和准确性。