常见NoSQL数据库类型
1.键值对数据库:redis
2.列式存储数据库:HBase
3.文档型数据库:MongDB
4.图形数据库(存储的是数据之间的关系):Neo4J
缓存数据的分类:
实时同步数据:要求数据库中的数据发生变化立刻刷新到缓存中(商品的价格,数量)
阶段性同步:没有必要和数据库中的要求一致,相差不大就可以(官网的销售额,用户数)
redis缓存特性
- 性能极高:读的速度能到达11w/s,写可以到达8w/s,1.redis是采用c语言编写, 2.redis所有的数据操作都是在内存中进行的,3.redis源码非常精细
- 简单稳定:redis源码很少,早期版本只有2w行左右,redis3.0增加了集群功能,代码变化到5w行左右
- 持久化:redis内存中的数据可以进行持久化,有AOF/RDB两种方式
- 高可用集群:redis提供了高可用的集群功能,确保了redis的可靠性
- 丰富的数据类型:redis是一个key-value存储系统,支持存储的value类型很多,包括String(字符串),LIst(链表),Set(集合),Zset(有序集合),Hash(哈希类型)等常用五种类型,和Bitmap(用于大数据量的二值性统计:平台活跃用户的统计,支持类统计,考勤类统计),HyperLogLog(用于对数据量超级庞大的日志做去重统计),Geospatial(用于地理位置相关的计算)类型
- 强大的功能:提供了数据国企功能,发布/订阅功能,简单事务功能,还支持Lua脚本扩展功能
- 客户端语言广泛:redis提供了简单的TCP通信,编程语言可以方便的接入进去
- 支持ACL(Access Control List,UGO)权限控制:redis引入了该功能可以针对不同用户定制不同的用户权限
- 支持多线程IO模型:redis前面的版本采用的是单线程模型,从6.0之后采用的是多线程模式
TIP:
ACL和UGO的区别:https://blog.csdn.net/Andrew__feng/article/details/107668542
redis的IO模型
redis客户端提交的各种请求是如何被最终处理的?redis处理客户端请求采用的处理架构,成为redis的IO模型
- 单线程模型:所有的请求交给一个线程执行,socket链接降接收到的事件交给事件分化期器,事件分化器将任务发给任务队列,任务队列交给线程,线程在调用不同的事件处理器进行处理(多路复用)
- 混合线程模型:从Redis 4.0版本开始,Redis中就开始加入了多线程元素。处理客户端请求的仍是单线程模型,但对于一些比较耗时但又不影响对客户端的响应的操作,就由后台其它线程来处理。例如,持久化、对AOF的rewrite、对失效连接的清理等。
- 多线程模型:多钱程Io模型中的“多钱程”仅用于接受、解析客户端的请求,然后将解析出的请求写入到任务队列。而对具体任务(命令)的处理,仍是由主线程处理。这样做使得用户无需考虑线程安全问题,无需考虑事务控制,无需考虑像LPUSH/LPOP等命令的执行顺序问题。
redis各种IO模型的优缺点
- 单线程模型:
优点:可维护性高,不存在并发读写情况,也就不存在执行顺序的不确定性,不存在线程切换开销,不存在死锁问题,不存在枷锁开锁的开销,
缺点:性能会受到影响,且由于单线程只使用一个处理器,会造成处理器的浪费 -
多线程模型:
优点:其结合了多线程与单线程的优点,避开了他们的所有不足
缺点:该线程没有明显的不足,其唯一的不足就是不是一个真正意义上面的多线程,所以,多性能还是有一定的影响
TIP:
多路复用技术:常见的多路复用技术有三种:select模型,poll模型,epoll模型
redis采用的多路复用技术会根据不同的平台进行决策,如果没有较好的多路复用技术的时候就会选择select作为底牌
外带链接(受益匪浅):https://segmentfault.com/a/1190000003063859#item-3-13
select模型:select本质上是通过设置或者检查存放fd标志位的数据结构来进行下一步处理,这样带来了一下的缺点
- 单个进程可以监视的文件描述符被限制,可以监视的端口有限,32位机器是一个可以存放1024个,64位是2048个
- 对socket是进行线性扫描的,采用轮询的方法,效率低
- 需要维护一个用来存放大量fd(文件描述符的数组,万物皆文件)的数据结构,开销较大
- 发现事件后返回,但是还是需要遍历rset(是一个bitmap的数据结构,存放的是对应文件描述符的地址,当发现事件后将相应数据置位),来进行对比判断时候是该文件描述符有数据需要进行处理
poll模型: poll本质和select没有明显的区别,他将用户传入的数组拷贝到内核空间,然后查询每个fd对应的设备状态,如果设备就绪则在设备等待队列中加入一项并继续遍历,如果遍历完所有的fd后没有发现就绪设备,则挂起当前进程,知道设备就绪或则主动超时,被唤醒后他又要再次遍历fd。这个过程经历了多次无畏的遍历。他没有最大链接数的限制,它采用的是链表来存储,但是他还是有如下的缺点
- 大量的fd的数组被整体复制于用户态和内额地址空间之间,而没有考虑这个是否有意义
-
poll是采用的水平触发,报告了该fd后没有被处理,那么下次poll时会再次报告该fd(相当于到达这个地方有需要返回进行再一次的处理)