Redis 基础一
Redis简介
Redis是一个开源的使用ANSI C语言编写、遵守BSD协议、支持网络、可基于内存亦可持久化的日志型、Key-Value数据库,并提供多种语言的API。它通常被称为数据结构服务器,因为值(value)可以是 字符串(String), 哈希(Map), 列表(list), 集合(sets) 和 有序集合(sorted sets)等类型。——redis中文社区
Redis数据类型及常用命令
-
String(字符串)
string是redis最基本的类型,一个key对应一个value。
string类型是二进制安全的。意思是redis的string可以包含任何数据。比如jpg图片或者序列化的对象 。
string类型是Redis最基本的数据类型,一个键最大能存储512MB。
命令: SET,GET -
Hash(哈希)
Redis hash 是一个键值对集合。
Redis hash是一个string类型的field和value的映射表,hash特别适合用于存储对象。
命令:HMSET, HEGTALL -
List(列表)
Redis 列表是简单的字符串列表,按照插入顺序排序。你可以添加一个元素导列表的头部(左边)或者尾部(右边)。
命令:
存:push [key] [element ...]
取:lrange [key] [start] [end] -
Set(集合)
Redis的Set是string类型的无序集合。
集合是通过哈希表实现的,所以添加,删除,查找的复杂度都是O(1)。
命令:
存:sadd [key][element ...]
取:smembers [key] -
zset(sorted set:有序集合)
Redis zset 和 set 一样也是string类型元素的集合,且不允许重复的成员。不同的是每个元素都会关联一个double类型的分数。redis正是通过分数来为集合中的成员进行从小到大的排序。zset的成员是唯一的,但分数(score)却可以重复。
命令:
存:zadd [key] [score] [member]
取:ZRANGEBYSCORE [key] [score_start] [score_end] -
HyperLogLog
Redis HyperLogLog 是用来做基数统计的算法,HyperLogLog 的优点是,在输入元素的数量或者体积非常非常大时,计算基数所需的空间总是固定 的、并且是很小的。
命令:
PFADD key element [element ...]
添加指定元素到 HyperLogLog 中。
PFCOUNT key [key ...]
返回给定 HyperLogLog 的基数估算值。
PFMERGE destkey sourcekey [sourcekey ...]
将多个 HyperLogLog 合并为一个 HyperLogLog -
Geo
Redis 的 GEO 是 3.2 版本的新特性。这个功能可以将用户给定的地理位置信息储存起来, 并对这些信息进行操作。
命令:
添加坐标点:GEOADD location-set longitude latitude member [longitude latitude member ...]
获取坐标点距离:GEODIST location-set location-x location-y [unit]
根据给定地理位置坐标获取指定范围内的地理位置集合:GEORADIUS location-set longitude latitude radius m|km|ft|mi [WITHCOORD] [WITHDIST] [ASC|DESC] [COUNT count]
根据给定地理位置获取指定范围内的地理位置集合:GEORADIUSBYMEMBER key member radius [m|km|ft|mi] [WITHCOORD] [WITHDIST] [ASC|DESC] [WITHHASH] [COUNT count] -
Pub/Sub
“发布/订阅”在redis中,被设计的非常轻量级和简洁,它做到了消息的“发布”和“订阅”的基本能力;但是尚未提供关于消息的持久化等各种企业级的特性。
一个Redis client发布消息,其他多个redis client订阅消息,发布的消息“即发即失”,redis不会持久保存发布的消息;
消息订阅者也将只能得到订阅之后的消息,通道中此前的消息将无从获得。
命令:
PSUBSCRIBE pattern [pattern ...]
订阅一个或多个符合给定模式的频道。
PUBSUB subcommand [argument [argument ...]]
查看订阅与发布系统状态。
PUBLISH channel message
将信息发送到指定的频道。
PUNSUBSCRIBE [pattern [pattern ...]]
退订所有给定模式的频道。
SUBSCRIBE channel [channel ...]
订阅给定的一个或多个频道的信息。
UNSUBSCRIBE [channel [channel ...]]
指退订给定的频道。
redis 常见问题
- redis雪崩
雪崩原因:
同一时间大面积redis key失效,这一时间redis形同虚设,此时刚好又有大量请求,这些请求直接同时查询到数据库,导致数据崩溃.
解决办法:
雪崩的产生原因是因为大量热点key的失效时间相同,所以在存数据的时候给每个key增加一个随机时间就能解决. - redis穿透
缓存穿透原因:
缓存穿透是指缓存和数据库中都没有的数据,而用户不断发起请求,用户进行请求,缓存中不存在,查询数据库,数据库中数据也不存在,当这样的请求(无意义请求)量过大,导致数据库压力过大,最后数据库崩溃.
解决办法:
在接口层增加校验,比如用户鉴权校验,参数做校验,不合法的参数直接代码Return,或者进行数据库查询时,无法查到数据,也进行redis储存,储存的值为null,或者其他无意义数据,并且将过期时间设置很短(太长会影响正常数据使用),这样就能防止穿透.还可以在网关层进行IP限制,对单个IP每秒访问次数超出阈值的IP都拉黑.
使用布隆过滤器(Bloom Filter)这个也能很好的防止缓存穿透的发生,他的原理也很简单就是利用高效的数据结构和算法快速判断出你这个Key是否在数据库中存在,不存在你return就好了,存在你就去查了DB刷新KV再return. - redis击穿
缓存击穿原因:大量请求都请求到一个热点key,当这个key过期的瞬间,大量请求直接查询数据库,导致数据压力过大崩溃.
解决办法:多个线程同时去查询数据库的这条数据(热点数据),那么可以在第一个查询数据的请求上使用一个互斥锁来锁住它。其他的查询走到这一步拿不到锁就等着,等第一个线程查询到了数据,然后做缓存。后面的线程进来发现已经有缓存了,就直接走缓存。或者直接设置热点数据永不过期.