携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第23天,点击查看活动详情
项目开发即将进入尾声。在这最后几次撰写中,主要针对的是代码规范需求来完成
Redis
Redis为nosql型数据库
那么,与mysql等sql型数据库相比有哪些不同呢?
SQL:
- 结构化
- 关联的
- SQL查询
- ACID(事务的四大原则)
nosql:
- 非结构化
- 无关联的
- 非sql
- BASE(只需满足基本原则)
数据类型:
String:底层使用SDS存储
使用SDS有什么好处,为什么不用C语言字符串?
1
因为用c字符串,程序必须遍历整个字符串,复杂度为O(N)
而SDS通过访问len属性就可以得到长度,复杂度为O(1)
2
c容易造成缓冲区溢出
举例:在进行修改属性时,要是忘记为新属性开辟相应的空间,那么该新属性会占用下一属性的空间并覆盖导致出现错乱
SDS在进行修改时,API会自动将SDS的空间扩展至执行修改所需的大小,然后才执行实际的修改,这样就不会出现缓冲区溢出问题
3
每次增长或缩短一个c字符串,程序都要对给字符串数组进行一次内存重分配操作,对于Redis这种追求速度的数据库来说十分耗时
而SDS有自己的优化策略进行解决
SDS的空间分配策略
空间预分配
空间预分配用于优化SDS的字符串增长操作
在进行增长后,len小于1MB的话,len将和free相等,也就是说此时的实际长度为2len+1
如果len大于1MB,那么程序会分配1MB的未使用空间。举例:如果在进行增长后,len变为30MB,30MB>1MB,那么free为1MB,所以实际长度为30MB+1MB+1byte
通过空间预分配策略,Redis可以减少连续执行字符串增长操作所需的内存重分配。
在扩展SDS空间之前,SDS API会先检查未使用空间是否足够,如果足够就会直接使用未使用空间
惰性空间释放
惰性空间释放用于优化SDS的字符串减少操作
在进行减少操作后,空间并不会释放掉,这些未使用空间可能会在后续的字符串添加上派上用场。