读写锁的应用

背景

当我们修改了短链接分组时,需要获取写锁;当我们自增短链接监控记录全局访问 PV、UV、UIP 时,获取读锁。

为什么需要读写锁?因为如果 Gid 变更后,新增短链接监控获取的是旧的 Gid,自增监控记录就会统计错误问题。

例子

我们假设没有读写锁,流程如下:

  1. 线程 A 将短链接分组从 6688ja 变更为 8866ja。注意,这个是准备要修改,还没有执行成功;
  2. 同时记录短链接监控线程 B 获取短链接分组为 6688ja,准备进行自增 PV、UV、UIP 数据;
  3. 此时线程 A 将短链接分组成功将 6688ja 变更为 8866ja
  4. 线程 B 自增短链接 PV、UV、UIP 开始执行,但执行失败,因为已经没有了对应短链接的 6688ja 分组。

为此,我们需要将短链接修改和监控数据自增隔离开来,以此来保障数据准确性。

自增执行 SQL 语句:

1
2
3
4
5
6
7
8
9
<!-- 自增短链接访问次数 -->
<update id="incrementStats">
UPDATE t_link
SET total_pv = total_pv + #{totalPv},
total_uv = total_uv + #{totalUv},
total_uip = total_uip + #{totalUip}
WHERE gid = #{gid}
AND full_short_url = #{fullShortUrl}
</update>

为什么用读写锁而不是用分布式锁?

因为分布式锁是串行化,吞吐量较低。读写锁中有两个锁种类,读锁和读锁之间是可以共享的,写写和读写才是互斥的。

这里 fullShortUrl 全局唯一,那么 UV、PV 这些自增时为什么要带 gid 这个条件?如果不带 gid,那么是不是就可以省略读写锁了?

因为咱们短链接表是按照 gid 分表的,如果不加就会触发读扩散问题。


读写锁的应用
http://example.com/2024/03/15/短链接/读写锁的应用/
作者
sxswldy
发布于
2024年3月15日
许可协议