【Redis笔记】基础

Redis为什么有多个库?
Redis默认有16个库,使用select命令切换,Redis中的库和关系型数据库不一样,Redis中的库可以理解为“命名空间”,且不支持独立密码。Redis多数据库目的是为了对数据隔离,防止key冲突。

Redis为什么速度快?
1、完全基于内存,绝大部分请求是纯粹的内存操作,非常快速。
2、类似于HashMap,HashMap的优势就是查找和操作的时间复杂度都是O(1);
3、采用单线程,避免了不必要的上下文切换和竞争条件,也不存在多进程或者多线程导致的切换而消耗 CPU,不用去考虑各种锁的问题,不存在加锁释放锁操作,没有因为可能出现死锁而导致的性能消耗;
4、使用多路I/O复用模型,非阻塞IO;

Redis为什么是单线程的?
官方FAQ表示,因为Redis是基于内存的操作,CPU不是Redis的瓶颈,Redis的瓶颈最有可能是机器内存的大小或者网络带宽。既然单线程容易实现,而且CPU不会成为瓶颈,那就顺理成章地采用单线程的方案了
降低了复杂度,不用去考虑各种锁的问题,不存在加锁释放锁操作,没有因为可能出现死锁而导致的性能消耗,同时保证了线程安全

注意:这里我们一直在强调的单线程,只是在处理我们的网络请求的时候只有一个线程来处理,一个正式的Redis Server运行的时候肯定是不止一个线程的,这里需要大家明确的注意一下!例如Redis进行持久化的时候会以子进程或者子线程的方式执行

最佳实践

key设计

Redis的key允许有多个单词形成层级结构,“:”分隔,如:业务名称:数据名:id

set login:user:1 value    # 登录业务保存用户信息
set like:user:1 value      # 收藏业务保存用户信息

优点:

  • 可读性强
  • 避免key冲突
  • 方便管理

拒绝bigkey,防止慢查询

  • string类型控制在10k以内
  • hash、lish、set、zset元素个数不要超过1000

bigkey的危害:

  • 网络阻塞
    对BigKey执行读请求时,少量的QPS就可能导致贷款被占满,导致请求变慢
  • 数据倾斜
    BigKey所在的Redis实例内存使用率远超其他实例,无法使数据分片的内存资源达到均衡
  • Redis阻塞
    对元素较多的hash、list、set、zset等做运算会耗时久,使主线程被阻塞
  • CPU压力
    对BigKey的数据序列化和反序列化会导致CPU使用率飙升

如何发现bigkey:
redis-cli --bigkeys
scan扫描
第三方工具,如Redis-Rdb-Tools
网络监控

控制key的声明周期:

建议使用expire设置过期时间,尽量打散过期时间,不要集中过期

禁用命令:

禁止线上使用keys、flushall、flushdb等,通过redis的rename机制禁掉命令,或者使用scan的方式渐进式处理。因为redis是单线程执行,容易导致线上不可用.
scan命令是通过游标分步进行,不会阻塞线程,提供count参数,不是结果数量,是Redis单次遍历字典数量,同keys一样也提供模式匹配功能。
scan 0 match user_token* count 5 #从0开始遍历,返回新游标,下次查询从新游标开始遍历

合理使用select:

redis的多数据库较弱,使用数字进行区分,很多客户端支持较差,同时多业务用多数据库实际还是单线程处理,会有干扰

尽量使用批量操作提高效率:

原生命令:例如mget、mset;非原生命令:可以使用pipeline提高效率。
但要注意控制一次批量操作的元素个数(例如500以内,实际也和元素字节数有关)。

通用命令

命令文档

help

查看命令的帮助文档

help keys    --查看keys命令的帮助文档

keys

查看符合模式的所有key
*代表多个字符,?代表单个字符

keys *	                  --查询所有key
keys list*	          --查询list开头的key
KEYS *name*            --查询包含name的所有key
KEYS a??            --查询包含a开头、共3个字符的所有key

DEL

删除缓存

del key1 key2 key3	                 

exists

查看指定key的缓存是否存在

exists a		  

type

查询键对应的value类型

type key1	          

expire

设置缓存时间,到期自动删除,单位秒

expire key 10  

ttl

查看剩余过期时间(-2表示已过期)

ttl key	                  

其他命令

flushall		  --清空全部库数据
flushdb			  --清空当前库数据
set a aaa [EX seconds] [PX milliseconds]		--设置过期时间EX表示秒     PX表示毫秒
move a 1		  --移除a,1代表当前库
posted @ 2019-12-22 10:33  .Neterr  阅读(508)  评论(0编辑  收藏  举报