Redis是什么
Redis(Remote Dictionary Server),即远程字典服务。
是一个开源的、使用 ANSI C 语言编写的,支持网络、可基于内存亦可持久化的键值(Key-Value)型 NoSQL 数据库。
Redis会周期性的把更新的数据写入磁盘或者把修改操作追加的记录文件,并且在此基础上实现了master-slave(主从)同步。
免费和开源!是当下最热门的NoSQL技术之一!
Redis能干嘛?
1.内存存储(效率高),持久化,内存中是断电即失,所以说持久化很重要(rdb,aof)
2.效率高,用于高速缓存
3.发布订阅系统
4.地图信息分析
5.计时器,计数器(浏览量!)
特性
1.多样的数据类型
2.持久化
3.集群
4.事务
Redis是单线程的?
Redis 6.0 以前
完全单线程:网络 IO + 命令执行 全部由一个线程处理。
为什么单线程还这么快?
纯内存操作
单线程避免了线程切换和锁竞争
非阻塞 IO 模型(epoll/kqueue)
Redis 6.0 及以后
命令执行依然是单线程
网络 IO 采用多线程(接收请求、发送数据)
核心:命令处理还是单线程,保证原子性、无竞争
面试最标准回答(直接背)
Redis 命令执行阶段是单线程的,所以不存在线程安全问题;
Redis 6.0 之后引入了多线程 IO,用来提升网络读写效率,但核心指令处理依旧是单线程。
Redis是C语言写的,官方提供的数据为 10W+ 的QPS。这完全不比 key-value的Memcache差!
Redis为什么单线程还这么快!
1.误区1:高性能的服务器一定是多线程的!
2.误区2:多线程一定快(CPU上下文会切换)
CPU > 内存 > 硬盘
核心:redis是将所有的数据全部放在内存中,所以说使用单线程去操作,效率就是最高的。多线程(CPU上下文会切换,这是一个耗时的操作!),对于内存系统来说,如果没有上下文切换,效率就是最高的。多次读写都是在一个CPU上,在内存情况下,这个就是最佳的方案。
五大数据类型
Redis 是一个开源(BSD许可)的,内存中的数据结构存储系统,它可以用作数据库、缓存和消息中间件。 它支持多种类型的数据结构,如 字符串(strings), 散列(hashes), 列表(lists), 集合(sets), 有序集合(sorted sets) 与范围查询, bitmaps, hyperloglogs 和 地理空间(geospatial) 索引半径查询。 Redis 内置了 复制(replication),LUA脚本(Lua scripting), LRU驱动事件(LRU eviction),事务(transactions) 和不同级别的 磁盘持久化(persistence), 并通过 Redis哨兵(Sentinel)和自动 分区(Cluster)提供高可用性(high availability)。
Redis-Key

String 字符串

String类型的使用场景:value除了我们字符串还可以是我们的数字!
-
计数器
-
统计多单位的数量 mset uid:{ID}:{关注量} uid:{ID}:{粉丝量}。。。
-
粉丝数
-
对象缓存存储
List 列表
在redis里面,我们可以list玩成栈,堆,阻塞队列!
所有的list命令都是l开头的,Redis不区分大小写
list 有序可重复

-
他实际上是一个链表 ,before node after ,left ,right 都可以插入值
-
如果key 不存在,创建新的链表
-
如果key存在,新增内容
-
如果移除了所有值,空链表 便不存在
-
在两边插入,或者改动值,效率最高!中间元素,相对来说效率会低一点
场景:消息排队! 消息队列 (Lpush Rpop) ,栈(Lpush Lpop)
Set 集合
set 无序 不重复

微博 A用户将所有关注的人放在一个set集合中!将他的粉丝也放在一个集合中!
共同关注,共同爱好,二度好友,推荐好友!( 六度分割理论)
Hash 哈希
Map集合 key-map!只是这个值是一个map集合!本质和String 类型没有太大区别,还是一个简单的key-value!

hash变更的数据user name age,尤其是用户信息之类的,经常变动的信息!hash更适合于对象存储,String更加适合字符
Zset 有序集合
在set的基础上,增加了一个值。
set k1 v1
zset k1 score1 v1

案例思路
set排序 存储班级成绩表,工资表排序!
普通消息-1, 重要消息-2 带权重进行判断!
排行榜应用实现,取Top N测试!
三种特殊数据类型
geospatial 地理位置
朋友的定位,附近的人,打车距离计算?
Redis的Geo在Redis3.0版本就推出了,这个功能可以推算地理位置的信息,两地之间的距离,方圆几里的人!
hypeloglog 可以统计基数
什么是基数?
A{1,3,5,7,8,7}
B{1,3,5,7,8}
基数:不重复的元素的个数 =5 可以接受误差!
简介:
Redis2.8.9版本更新了Hyperloglog数据结构!
Redis Hyperloglog基数统计的算法!
优点:
占用的内存是固定,2^64不同的元素的基数,只需要费12KB的内存!如果要从内存角度比较的话,Hyperloglog首选!
bitmaps 位存储
统计用户信息,活跃,不活跃!登录,未登录!打开,未打卡!两个状态的都可以使用bitMaps
Bitmaps位图,数据结构!都是操作二进制进行记录,就只有0和1两个状态!
365天=365bit 1字节=8bit 46个字节左右。
Redis持久化
Redis是内存数据库,如果不将内存中的数据保存到磁盘中,那么一旦服务的进程退出,服务的数据库状态也会消息。所以Redis提供了持久化功能!
RDB(Redis DataBase)
什么是RDB
在主从复制中,rdb就是备用的,在从机上面!
在指定的时间间隔内将内存中的数据集快照写入磁盘,也就是Snapshot快照,它恢复时是将快照文件直接读到内存中。
Redis会单独创建(fork)一个子进程来行持久化,会将数据写入到一个临时文件中,待持久化过程都结束了,再用这个临时文件替换上次持久化好的文件。整个过程中,主进程不进行任何IO操作的。这就确保了极高的性能。如果需要进行大规模数据的恢复,且对于数据恢复的完整性不是非常敏感,那么RDB方式要比AOF方式更加高效。RDB的缺点是最后一次持久化后的数据可能丢失。默认都是RDB。
触发机制
1.save的规则满足情况下,会自动触发rbd规则
2.执行flushall命令,也会触发我们的rdb规则
3.退出redis,也会产生rdb文件!
4.备份就会自动生成一个dump.rdb
如何恢复rdb文件
1.只需要将rdb文件放在我们redis启动目录就可以,redis启动的时候会自动检查dump.rdb文件,恢复其中的数据!
优点:
1.适合大规模的数据恢复!
2.对数据的完整性要求不高!
缺点:
1.需要一定的时间间隔进行操作!如果redis意外宕机了,这个最后一次修改的数据就没有了。
2.fork进程的时候,会占用一定的内存空间。
AOF (Append only File)
将我们的所有命令都记录下来,history,恢复的时候就把这个文件全部再执行一遍!
以日志的形式来记录每一个写操作,将Redis执行过得所有指令记录下来(读操作不记录),之追加文件但不可以改写文件,redis启动之初会读取改文件重新构建数据,换言之,redis重启的话就会根据日志文件的内容将与指令从前到后执行一次已完成数据的恢复工作。Aof保存的是appendonly.aof文件
默认是不开启的,需要手动配置!我们只需要将reids配置文件中的appendonly改为yes就开启了aof!
重启,redis就可以生效了!
重写规则说明
aof默认就是文件的无限追加,文件会越来越大!

优点:
1.每一次修改都同步,文件的完整会更加好!
2.每秒同步一次,可能会丢失一秒的数据!
3.从不同步,效率最高!
缺点:
1.相对于数据文件来说,aof远远大于rdb,修复的速度也比rdb慢!
2.Aof运行效率也要比rdb慢,所以我们redis默认配置是rdb
补充
1.RDB持久化方式能够在指定的时间间隔内对你的数据进行快照存储
2.AOF持久化方式记录每次对服务器写的操作,当服务器重启的时候就会重新执行这些命令来恢复原始的数据,AOF命令以Redis协议追加保存每次写的操作到文件末尾,Redis还能对AOF文件进行后台重写,使得AOF文件的体积不至于过大。
3.只做缓存,如果你希望你的数据在服务器运行时候存在,可以不使用任何持久化
4.同时开启两种持久化方式
-
在这种情况下,当redis重启的时候会优先载入AOF文件来恢复原始的数据,因为在通常情况下AOF文件保存的数据集要比RDB文件保存的数据要完整。
-
RDB的数据不实时,同时使用两者时服务器重启也只会找AOF文件,那要不要只是用AOF?建议不要,因为RDB更适合用于备份数据库(AOF在不断变化不好备份),快速重启,而且不会有AOF可能潜在的Bug,留着作为万一的手段。
5.性能的建议
-
因为RDB文件只用作后备用途,建议只在Slave上持久化RDB文件,并且只要15分钟备份一次就够了。只保留save 900 1 这个规则。
-
如果Enable Aof ,好处是在最恶劣的情况下也只会丢失不超过两秒数据,启动脚本较简单只load自己的AOF文件就可以了。代价一是带来了持续的IO,二是AOF rewrite的最后将re
write过程中产生的新数据写到新文件造成的阻塞几乎是不可避免的,只要硬盘许可,应该尽量减少AOF rewrite的频率。AOF重写的基础默认值为64M,太小了,可以设置为5G以上。、
-
如果不Enable Aof .仅靠Master-Slave Repllcation实现高可用也可以,能省掉一大笔IO,也减少了rewrite时带来的系统波动。代价是如果Master/Slave同时倒掉(断电),可能会丢失十几分钟的数据,启动脚本也要比较两个Master/Slave中的RDB文件,载入较新的那个,微博就是这种架构。