五.redis
五.redis
5.1 什么是CDN
CDN的全称是Content Delivery Network,即内容分发网络。
CDN的全称是Content Delivery Network,即内容分发网络
CDN是构建在现有网络基础之上的智能虚拟网络,依靠部署在各地的边缘服务器
通过中心平台的负载均衡、内容分发、调度等功能模块,使用户就近获取所需内容,降低网络拥塞,提高用户访问响应速度和命中率。
5.2 CDN的原理
CDN的基本原理是广泛采用各种缓存服务器,将这些缓存服务器分布到用户访问相对集中的地区或网络中
在用户访问网站时,利用全局负载技术将用户的访问指向距离最近的工作正常的缓存服务器上,由缓存服务器直接响应用户请求。
通过在网络各处放置节点服务器所构成的在现有的互联网基础之上的一层智能虚拟网络,能够实时地根据网络流量和各节点的连接、负载状况以及到用户的距离和响应时间等综合信息将用户的请求重新导向离用户最近的服务节点上。
其目的是使用户可就近取得所需内容
,解决 Internet网络拥挤的状况,提高用户访问网站的响应速度。
5.3 首先,介绍一下Redis过期删除策略
Redis对于过期的key,有两种删除策略:
定期删除
redis 会将每个设置了过期时间的 key 放入到一个独立的字典中,以后会定期遍历这个字典来删除到期的 key。
Redis 默认会每秒进行十次过期扫描(100ms一次),过期扫描不会遍历过期字典中所有的 key,而是采用了一种简单的贪心策略。
1.从过期字典中随机 20 个 key;
2.删除这 20 个 key 中已经过期的 key;
3.如果过期的 key 比率超过 1/4,那就重复步骤 1;
注意这里是随机抽取的。为什么要随机呢?你想一想假如 redis 存了几十万个 key ,每隔100ms就遍历所有的设置过期时间的 key 的话,就会给 CPU 带来很大的负载。
惰性删除
所谓惰性策略就是在客户端访问这个key的时候,redis对key的过期时间进行检查,如果过期了就立即删除,不会给你返回任何东西。
5.4 为啥需要两种删除策略呢?
定期删除可能会导致很多过期key到了时间并没有被删除掉。所以就有了惰性删除。假如你的过期 key,靠定期删除没有被删除掉,还停留在内存里,除非你的系统去查一下那个 key,才会被redis给删除掉。这就是所谓的惰性删除,即当你主动去查过期的key时,如果发现key过期了,就立即进行删除,不返回任何东西.
总结:定期删除是集中处理,惰性删除是零散处理。
5.5 然后,再介绍Redis淘汰策略.
1.no-envicition:
该策略对于写请求不再提供服务,会直接返回错误,当然排除del等特殊操作,redis默认是no-envicition策略。
2.allkeys-random:
从redis中随机选取key进行淘汰
3.allkeys-lru:
使用LRU(Least Recently Used,最近最少使用)算法,从redis中选取使用最少的key进行淘汰
4.volatile-random:
从redis中设置过过期时间的key,进行随机淘汰
5.volatile-ttl:
从redis中选取即将过期的key,进行淘汰
6.volatile-lru:
使用LRU(Least Recently Used,最近最少使用)算法,从redis中设置过过期时间的key中,选取最少使用的进行淘汰
7.volatile-lfu:
使用LFU(Least Frequently Used,最不经常使用),从设置了过期时间的键中选择某段时间之内使用频次最小的键值对清除掉
8.allkeys-lfu:
使用LFU(Least Frequently Used,最不经常使用),从所有的键中选择某段时间之内使用频次最少的键值对清除
5.6 那么,如何设置淘汰策略呢?
config get maxmemory-policy //获取当前内存淘汰策略
config set maxmemory-policy valatile-lru //通过命令修改淘汰策略
5.7 如何配置Redis能使用的最大的内存大小
Redis是基于内存key-value键值对的内存数据库,我们安装完数据库之后,内存往往会受到系统内存大小的限制,我们也可以配置redis能使用的最大的内存大小.
两种方式配置redis的内存:
- 通过配置文件修改
- 通过客户端修改
第一种方式:
在redis根目录中找到redis.conf文件
# 设置 Redis 最大使用内存大小为100M
maxmemory 100mb //指定最大内存为100mb
当 Redis 使用的内存超过 100Mb 时,就开始对数据进行淘汰。
#配置文件
maxmemory <bytes>
下面的写法均合法:
maxmemory 1024000
maxmemory 1GB
maxmemory 1G
maxmemory 1024KB
maxmemory 1024K
maxmemory 1024MB
...
第二种方式:
通过客户端修改
在服务器上输入redis-cli之后进入redis客户端,通过命令动态修改redis内存大小
//设置Redis最大占用内存大小为100M
127.0.0.1:6379> config set maxmemory 100mb
//获取设置的Redis能使用的最大内存大小
127.0.0.1:6379> config get maxmemory
如果不设置,或者设置最大内存大小为0,在64位操作系统下,Redis不限制内存大小,在32位操作系统,Redis最多使用3GB内存
5.8 Redis数据持久化RDB与AOF原因,用法
原因:
Redis 虽然是一个内存级别的缓存程序,也就是redis 是使用内存进行数据的缓存的它把数据都存储在了内存中,如果Redis服务器出现了意外,比如宕机、断电等情况,那么内存中的数据就会全部丢失。所以必须有一种机制可以把内存中的数据保存到磁盘里面,为了解决这个问题,Redis提供了RDB和AOF两种持久化机制,这也是Redis的重要特性之一。
RDB用法:(默认开启)
称为Redis数据快照。
手动执行:
可以用SAVE和BGSAVE命令来手动生成RDB文件,但这两者有所不同。
SAVE命令
- SAVE命令会阻塞Redis进程,直到RDB文件创建完毕为止,在这之前,服务器不能处理任何命令请求。
BGSAVE命令
- BGSAVE命令会创建一个子进程来创建RDB文件,所以在创建过程中,Redis服务器仍然可以处理客户端的命令请求,但是会拒绝SAVE、BGSAVE和BGREWRITEAOF三个命令的执行。
save 900 1 #在900秒(15分钟)之内,对数据库进行了至少1次修改,则执行一次BGSAVE
save 300 10 #在300秒(5分钟)之内,对数据库进行了至少10次修改,则执行一次BGSAVE
save 60 10000 #在60秒之内,对数据库进行了至少10000次修改,则执行一次BGSAVE
AOF原因
目的是为了解决生成RDB文件后数据不能实时一致的问题,所以它采用日志的形式来记录每个写操作,并追加到文件中。Redis重启会根据日志文件的内容将写命令从前到后执行一遍来恢复数据。
AOF使用(默认关闭)
AOF持久化功能的实现可以分为命令追加(append)、文件写入、文件同步(sync)三个步骤:
命令追加
服务器在执行完一个写命令后,会以协议格式将被执行的写命令追加到服务器状态的aof_buf缓冲区的末尾。aof缓冲区是redisServer结构体维护的一个SDS结构的属性。
struct redisServer{
//....
//AOF缓冲区
sds aof_buf;
//...
};
文件写入
将aof缓冲区的数据写入到AOF文件,此时数据并没有写入到硬盘,而是拷贝到了内核缓冲区page cache(操作系统),等待内核将数据写入硬盘;具体内核缓冲区的数据什么时候写入到硬盘,由内核决定。
文件同步
这个过程是将内核缓冲区中的数据写入到硬盘中的AOF文件中。
如果由内核决定将内核数据写入硬盘的话,如果服务器宕机,那么就会丢失数据。为了解决这个问题,系统提供了(fync和fdatasync)两个同步函数,它们可以强制让操作系统立即将缓冲区中的数据写入到硬盘,以及三种策略:
always:同步写回,每个写命令执行完立刻同步地将日志写回磁盘。(性能最差,最多丢失一个写指令的数据)
everysec(默认):每秒执行一次。(是性能和数据安全性的折中方案,最多也就丢一秒的数据)
no:根据操作系统和资源的情况,一定时间执行一次,时间不确定。(性能最好,可能会丢失上次同步AOF文件之后的所有写命令数据)
5.9 RDB VS AOF
数据可靠性
RDB:可能会丢失最后一次快照之后的数据。如果RDB持久化过程中服务器宕机了,那么就会丢失这一次的数据。
AOF:可能会丢失最后一次(或一秒)写操作的数据。如果Redis刚刚执行完一个写命令,还没来得及写AOF文件就宕机了,那么就会丢失这一条数据【当然也得看它配置的策略,如果配置的是always(同步),那就丢一条,配置的everysec(每秒)那就会丢1秒的数据】,但它也比RDB更加靠谱一些。
性能:
RDB:备份和数据恢复比较快,适合做数据恢复。RDB存的是原生数据,所以直接加载到内存中即可。
AOF:写性能较高【RDB是对整个物理中的数据的快照,AOF则仅仅是记录每次写命令】,但数据恢复速度相对较慢【AOF需要对命令从头到尾再执行一次】。
存储空间:
RDB:二进制文件,体积较小。
AOF:文本文件,体积较大。
使用场景:
RDB:适用于需要定期备份、大规模数据恢复、恢复速度要求比较快的场景。
AOF:适用于对数据完整性要求较高、数据存档的场景。
5.9 什么是Redis事务
Redis 事务的本质是一组命令的集合
。事务支持一次执行多个命令,一个事务中所有命令都会被序列化。在事务执行过程,会按照顺序串行化执行队列中的命令,其他客户端提交的命令请求不会插入到事务执行命令序列中。
Redis事务没有隔离级别:
批量操作在发送 EXEC 命令前被放入队列缓存,并不会被实际执行,也就不存在事务内的查询要看到事务里的更新,事务外查询不能看到。
Redis不保证原子性:
Redis中,单条命令是原子性执行的,但事务不保证原子性,且没有回滚。事务中任意命令执行失败,其余的命令仍会被执行。
Redis的事务总是具有ACID中的原子性、一致性和隔离性,当服务器运行在AOF持久化模式下,并且appendfsync选项的值为always时,事务也具有耐久性。
5.10 Redis为什么这么快
Redis是基于内存操作,需要的时候需要我们手动持久化到硬盘中
Redis高效数据结构,对数据的操作也比较简单
Redis是单线程模型,从而避开了多线程中上下文频繁切换的操作
使用多路I/O复用模型,非阻塞I/O
5.11 redis主从复制原理
总的来说主从复制功能的详细步骤可以分为7个步骤:
- 设置主节点的地址和端口
- 建立套接字连接
- 发送PING命令
- 权限验证
- 同步
- 命令传播
5.12 redis和MySQL的区别
两者的区别非常大。
Redis基于内存,读写速度快,也可做持久化,但是内存空间有限,当数据量超过内存空间时,需扩充内存,但内存价格贵。
MySQL基于磁盘,读写速度没有Redis快,但是不受空间容量限制,性价比高。
mysql是一个中小型的网络数据库,比oracle和sqlserver小, 但是并发能力远超过access这样的桌面数据库。
redis是一个支持网络、可基于内存亦可持久化的日志型、Key-Value数据库。
可以认为redis比mysql简化很多。
mysql支持集群。
现在大量的软件使用redis作为mysql在本地的数据库缓存,然后再适当的时候和mysql同步。大多数的应用场景是MySQL(主)+Redis(辅),MySQL做为主存储,Redis用于缓存,加快访问速度。需要高性能的地方使用Redis,不需要高性能的地方使用MySQL。存储数据在MySQL和Redis之间做同步。