叠甲:未详细看底层实现,只是大概看了一下涉及的api的源码,理解错的地方勿喷
问题背景
公司业务中用到了一个map,作用是存储需要屏蔽的数据,请求打过来后会去其中匹配 若命中则直接退出
该map的使用有以下几个特点:
- 存在多个请求同时读
- 单独通过协程去更新map,数据源是一个文件,定时扫描文件将其中的内容同步到map中
- 读多写少
- 读的时候大量数据其实不会命中map
- 写的时候每次其实只需要把文件diff的内容更新进map即可
解决方案
既然是存在并发读写,就考虑了两种方式
- sync.Map
- map加读写锁
一开始准备用第一种,但 最终选择了第二种
实际考虑
- 方式1的优点在于有现成api,直接无脑调用就行,但是对于上面的场景4来说会存在加两把🔐的问题,因为大量数据其实是miss的
之前其实只考虑了store的性能问题,因为每次只更新文件diff,所以加锁的概率很低,因为大部分的文件内容其实是命中Map的
- 说说对方案2的考虑,通过读写锁自己控制并发读写问题,最终形成了如下伪代码
更新环节
获取读锁
统计当前对当前map来说,文件中的哪些内容是新增的
释放读锁
如果存在新增的内容则获取写锁,并写入map // 通过这个过程避免无脑获取写锁更新map,不存在新内容就不获取写锁了
读取环节
傻瓜式的获取读锁,然后读取map就好了