主流应用架构
缓存中间件–Memcache和Redis的区别
Memcache(我这个是直接看别人复制过来的,没怎么见过这个中间件,所以就没管):
- 它非常简单易用,代码层次类似于Hash.
- 它支持简单数据类型.
- 不支持数据持久化存储,一旦服务器宕机,数据保存不下来的.
- 不支持mysql那样的主从同步.
- 不支持分片.
Redis
- 数据类型丰富,支持set.list等类型.
- 支持数据磁盘持久化存储.
- 支持主从同步.
- 支持分片.
Redis为什么能这么快
他们说可以达到十万+的QPS(QPS即query per second,每秒查询次数).
- Redis完全基于内存,绝大部分请求纯粹是内存操作,不会受到硬盘,IO等的线坠,执行效率高,Redis采用的是单进程-单线程的K-V数据库,C语言写的.
- 数据结构简单(key-value结构,类似于哈希表),对数据操作也简单,Redis不使用表,它的数据库不需要预定义或者强制要求用户对Redis存储的不同数据进行关联.
- 采用单线程,单进程也能处理 高并发(注意区分并行) 请求,想多核也可以启动多实例.
并发和并行的区别:
并发的关键是你有处理多个任务的能力,不一定要同时。
并行的关键是你有同时处理多个任务的能力。
例如:
你吃饭吃到一半,电话来了,你一直到吃完了以后才去接,这就说明你不支持并发也不支持并行。
你吃饭吃到一半,电话来了,你停了下来接了电话,接完后继续吃饭,这说明你支持并发。 (不一定是同时的)
你吃饭吃到一半,电话来了,你一边打电话一边吃饭,这说明你支持并行。
4. 使用多路复用I/O复用模型,即非阻塞IO,因为Redis是跑在单线程的,所有的操作都是按照顺序线性执行
的,但是由于读写操作,等待用户输入输出这些都是阻塞的,所以IO操作一般情况下往往不能直接返回,就会导致某一文件的IO阻塞,进而导致某个进程无法对其他客户端提供服务,而I/O多路复用就是为了解决这个问题而出现的.
FD: File Descripter, 文件描述符.
在操作系统中,一个打开的文件通过唯一的描述符进行引用
,该描述符是打开文件的元数据到文件本身的映射.
传统的阻塞I/O模型
当使用read或者write对某一个文件描述符进行读写时,如果当前FD不可读或者不可写,整个redis服务就不会对其他的操作做出响应,这就会导致整个服务不可用,所以,在需要处理多个客户端任务的时候,往往都不会使用阻塞模型,所以需要一种更高效率的IO模型来支持Redis的高并发处理,这就用到了多路I/O复用模型.
多路复用I/O复用模型
Select系统调用
select()可以同时监控多个文件描述符的可读,可写情况,当其中的某些文件描述符可读或者可写时,select()方法就会返回可读/可写的文件描述符个数
也就是说,select是负责监听文件是否可读或者可写的,那监听的任务交给select之后呢,我们的线程又可以继续去做别的事情而不会被阻塞了.
Redis采用的I/O多路复用函数: epoll/kqueue/evport(linux中)/select
这么多多路复用函数,那么Redis具体用哪个呢?
1. 因地制宜,因为redis需要在多个平台上运行,同时为了最大化的提高执行效率和性能,所以会根据编译平台的不同,选择不同的复用函数.
2. 优先选择时间复杂度为O(1)的I/O多路复用函数作为底层实现.
3. 以时间复杂度为O(N)的select作为保底.
4. 基于react设计模式监听I/O事件.