存储层以及缓存的一些想法
近日工作中有一个动作是去updateDB中的数据,更新了几十万条数据。更新完了,业务测试没有通过。但是在test环境是ok的。
首先说说公司的上线流程是 dev->test->uat->regression->live.
对应的是 开发-> 测试 -> 业务测试(需求方)-> 回归测试(测试对所有ticket进行整体回归) -> 上线这样一个过程。
因为之前是无脑更新,所以现在只能够看看是什么原因导致了这种情况。通过代码可以看到使用了redis作为缓存。追根溯源,在得到key之后通过ttl命令查看存活时间------
redis时间单位是秒,这个时间显然太长了,业务想要的结果肯定是立马生效的。也就是说在updateDB的同时应该去update redis。以免造成这种困扰。看了一把如何构造key。写个脚本把updateDB的动作改为update redis跑了一遍达到了目的。
那么这样的问题就变成了如何去更新DB的同时去更新缓存。向上面的情况就变成了分步,update DB,redis是单独了。最好额做法肯定是把两者绑定起来,提供一个接口或者格式把两者更新,删除绑定,这才是最佳的。这样把整体的逻辑打包,自然减少了风险。
之前还有另一点思考,关于sql的选择。
sql 选择
sql的选择大体分为了两种类型。
- 简单sql,一个sql只对单表进行筛选。
- 复杂sql,对多表进行join,筛选。
首先分析一下这两种sql的优劣:
简单sql
- 简单。
- sql一时爽,业务火葬场。降低了sql复杂度的同时必然就增加了业务逻辑代码的复杂度,join的功能不交给DB实现,就是去实现。
- 针对其进行缓存简单,更好的划分了资源力度的单位。update的时候对缓存以及DB更新可以是同时的。
复杂sql
- 复杂的sql减少了业务逻辑的处理,充分利用了DB的功能。多次查询变成了单次查询减少了连接数以及网络开销。
- 不利于缓存。sql查询出来的东西可能因为某些小的sql做了简单的update而导致整体的结果不可用。还有一些多表联合的update操作非常,一旦进行这种类型的操作就会造成几乎无法使用缓存。
基于以上的比较,在小系统初期,更加倾向于使用sql来替我们做并表查询,排序。当系统达到一定规模,DB会分库分表,这个时候做这种操作一方面实现难度增大,另一方面性能急剧下降。那么微服务化,构建统一的接口获取相关信息就变得更加重要了。