前言:先学会怎么使用,再看面试题比较好
redis常用数据类型:String(字符串),list(可以重复的集合),set(重复的集合),hash(类似于Map<String,String),zset(不重复的集合)
补充:redis不使用表,它的数据库不会预定义或者强制要求用户对redis对redis存储的不同数据进行关联,因此性能相对关系型数据库高出不止一个量级。其存储结构就是键值对,类似于hashMap,hashMap的优势就是查找和操作的时间复杂度都是O(1)的
面对多并发的请求,我们一般想到的是用多个线程来处理,将IO线程和业务线程分开,业务线程使用线程池来避免频繁创建和销毁线程,即便有一个线程阻塞了,也不会影响到其他请求。
在多核cpu的时代,为什么redis选择反其道而为之?准确的来说,redis的单线程结构是指主线程是单线程的,这里主线程包括IO事件的处理,以及IO对应的相关请求的业务处理。
此外,主线程还负责过期键的处理,父子协调,集群的协调等等。这些除了IO事件的逻辑,会被封装成周期性的任务,由主线程周期的处理。正因为采用单线程的设计,对于客户端所有读写请求都有一个主线程串行的处理,因此多个客户端同时对一个键进行读写操作的时候,就不会有并发的问题,避免了频繁的上下文切换和锁竞争,使得redis执行效率更高。
能并发并不是并行,并行性意味着服务器能够同时执行几个事情,具有多个计算单元,而并发性IO流,意味着能够让一个计算单元来处理多个客户端的流请求,redis使用单线程,配合上IO多路复用将大幅度地提升性能。在resis对cpu进行测试中,QPS峰值时cpu也没有跑满,所以cpu不是制约redis的性能瓶颈。在多核的cpu,可以启动多个redis实例。
补充:单线程只是在处理我们网络请求的时候,只有一个单线程来处理,一个正式的redis-server在运行的时候肯定不止一个线程的。例如在redis进行持久化的时候,会根据实际情况,以子进程或子线程的方式执行。
使用多路I/O复用模型,非阻塞IO所有的操作都是按照顺序,线性执行的,但是由于读写操作等待用户输入或输出,都是阻塞的,所以IO操作在一般情况下,往往不能直接返回,会导致某一文件的IO阻塞,进而导致整个进程无法对其他客户端提供服务,IO多路复用就是为了解决这个问题出现的。