redis 的应用场景和数据类型

一 REDIS的数据类型(重要)

常用的5种数据结构:

  • key-string:一个key对应一个值。

  • key-hash:一个key对应一个Map。

  • key-list:一个key对应一个列表。

  • key-set:一个key对应一个集合。

  • key-zset:一个key对应一个有序的集合。

另外三种数据结构:

  • HyperLogLog:计算近似值的。

  • GEO:地理位置。

  • BIT:一般存储的也是一个字符串,存储的是一个byte[]。

  • redis是一种高级的key-value的存储系统,其中的key是字符串类型,尽可能满足如下几点:

    1.key不要太长,最好不要操作1024个字节,这不仅会消耗内存还会降低查找效率

    2.key不要太短,如果太短会降低key的可读性

    3.在项目中,key最好有一个统一的命名规范(根据企业的需求)

    value最常用的五种数据类型:

    1.字符串(String):最常用的,一般用于存储一个值

    2.列表(List):使用list结构实现栈和队列结构

    3.集合(Set) :交集,差集和并集的操作

    4.有序集合(sorted set) :排行榜,积分存储等操作

    5.哈希(Hash):存储一个对象数据的

1.1字符串(string)

set key value  设定key持有指定的字符串value,如果该key存在则进行覆盖操作,总是返回"OK"

get key 获取key的value。如果与该key关联的value不是String类型,redis将返回错误信息,因为get命令只能用于获取String value,如果该key不存在,返回null

getset key value 先获取该key的值,然后在设置该key的值

incr key 将指定的key的value原子性的递增1.如果该key不存在,其初始值为0,在incr之后其值为1。如果value的值不能转成整型,如hello,该操作将执行失败并返回相应的错误信息。

decr key 将指定的key的value原子性的递减1.如果该key不存在,其初始值为0,在incr之后其值为-1。如果value的值不能转成整型,如hello,该操作将执行失败并返回相应的错误信息

incrby key increment 将指定的key的value原子性增加increment,如果该key不存在,器初始值为0,在incrby之后,该值为increment。如果该值不能转成整型,如hello则失败并返回错误信息。

decrby key decrement:将指定的key的value原子性减少decrement,如果该key不存在,器初始值为0,在decrby之后,该值为decrement。如果该值不能转成整型,如hello则失败并返回错误信息。

append key value:如果该key存在,则在原有的value后追加该值;如果该key不存在,则重新创建一个key/value。

setex key seconds value:设置key以及对应的value,还可以设置过期时间

setnx key value:当key不存在时,设置对应的value,当key存在时,不做任何操作

使用的场景

1.简单的缓存存储(最常用)

2.消息的失效性(过期时间的设置)

3.分布式锁的实现(redisson)

二  key -list

lpush key value value2 在指定的key所关联的list的头部插入所有的values,如果该key不存在,该命令在插入的之前创建一个与该key关联的空链表,之后再向该链表的头部插入数据。插入成功,返回元素的个数。

rpush key value value2  在该list的尾部添加元素。

lrange key start end  eg lrange key 0 -1 全部

lpushx key value:当key存在时,在头部插入value,否则将不插入

rpushx key value:在key的尾部插入value

lpop key:返回并弹出指定的key关联的链表中的第一个元素,即头部元素。

rpop key:从尾部弹出元素。

rpoplpush resource destination:将链表中的尾部元素弹出并添加到头部。

llen key:返回指定的key关联的链表中的元素的数量。

lset key index value:设置链表中的index的脚标的元素值,0代表链表的头元素,-1代表链表的尾元素。    根据下标来修改

lrem key count value   删除key 

count 大于0 从头删除   value  删除几个  

count小于0,则从尾向头遍历并删除。如果count等于0,则删除链表中所有等于value的元素。

linsert key before|after pivot value:在pivot元素前或者后插入value这个元素。

使用场景如下:

消息流的场景:

1.用户的id作为key,发送的消息作为value,例如:朋友圈发布,微博发布,公众号发布...

三  key - set  不允许出现重复的元素  无序

sadd key value1 value2…:向set中添加数据,如果该key的值已有则不会重复添加。

smembers key:获取set中所有的成员。

scard key:获取set中成员的数量

sismember key member:判断参数中指定的成员是否在该set中,1表示存在,0表示不存在或者该key本身就不存在。

srem key member1 member2… :删除set中指定的多个成员。

srandmember key:随机返回set中的一个成员。

sdiff key1 key2:返回key1与key2中相差的成员,而且与key的顺序有关,即返回差集。

sdiffstore destination key1 key2:将key1、key2相差的成员存储在destination上。

sinter key[key1,key2…]:返回交集

sinterstore destination key1 key2:将返回的交集存储在destination上。

sunion key1 key2:返回并集。

sunionstore destination key1 key2:将返回的并集存储在destination上

使用场景如下:

公司年会,随机抽奖小程序

1.把所有用户统一存入set集合中

2.查看所有抽奖人数

3.随机抽取指定得奖人数并从set集合中删除

实现:

1.sadd choujiang userid1,userid2,userid3...

2.smembers choujiang

3.spop choujiang [count]

微信点赞,微博收藏

1.点赞,创建集合并加入对应用户

2.取消点赞,从集合中删除对应用户

3.检查用户是否点过赞

4.获取点赞用户列表

5.获取点赞用户数量

实现:

1.sadd dianzan userid1,userid2,userid3...

2.srem dianzan userid1

3.sismember dianzan userid1

4.smembers dianzan

5.scard dianzan

可能认识的人推荐

1.两个集合取交集

实现:

1.sinter user1list,user2list...

2.sinterstore list user1list,user2list...

四  有序集合(sorted set)

zadd key score member score2 member2 … :将所有成员以及该成员的分数存放到sorted-set

zcard key:获取集合中的成员数量。

zcount key min max:获取分数在[min,max]之间的成员。

zincrby key increment member:设置指定成员的增加的分数。

zrange key start end [withscores]:获取集合中脚标为start-end的成员,[withscores]参数表明返回的成员包含其分数。

zrangebyscore key min max withscores返回分数在[min,max]的成员并按照分数从低到高排序。[withscores]:显示分数;[limit offset count]:offset,表明从脚标为offset的元素开始并返回count个成员。

zrank key member:返回成员在集合中的位置。

zrem key member[member…]:移除集合中指定的成员,可以指定多个成员。

zscore key member:返回指定成员的分数。

使用场景如下:

排行榜实现

1.对播放的视频,分数自增1

2.展示排行榜前十的视频

实现:

1.zincrby videos 1 video1id

2.zrevrangebyscore videos 100 0 withscores limit 0 9 (zrevrangebyscore从大到小排序)

四 Key -hash

hset key field value:为指定的key设定field/value对(键值对)。

hgetall key:获取key中的所有filed-vaule。

hget key field:返回指定的key中的field的值。

hmset key fields:设置key中的多个filed/value。

hmget key fileds:获取key中的多个filed的值。

hexists key field:判断指定的key中的filed是否存在。

hlen key:获取key所包含的field的数量。

hincrby key field increment:设置key中filed的值增加increment,如:age增加20。

使用场景如下:

购物车场景:

1.用户的id作为key

2.商品的id作为field(属性)

3.商品的数量作为value(属性值)

购物车操作:

1.用户添加购物车:hset cart:1001 20001 1 (id为1001的用户添加了一个id为20001的商品,数量为1个)

2.增加对应商品数量:hincrby cart:1001 20001 1

3.查询商品总数:hlen cart:1001

4.删除该用户的某个商品:hdel cart:1001 20001

5.查询该用户购物车信息:hgetall cart:1001

五 通用操作

keys patten:获取所有与patten匹配的key,*表示任意字符,?表示一个字符。

del key1 key2....:删除指定的key。

exists key:判断该key是否存在,1表示存在,0表示不存在。

rename key newkey:为当前key重命名。

expire key second:为当前key设置过期时间(单位:秒)。

ttl key:查看当前key剩余过期时间。

type key:查看当前key类型。

flushall: 删除所有key

六 reids中的消息的订阅和发布(不重要)

subscribe channel 订阅频道 例如:subscribe cctv5

publish channel content 在指定频道中发布内容 例如:publish cctv5 basketball

同时打开两个客户端,一个订阅频道,一个在频道中发布内容,订阅频道的客户端会接收到消息。

七 使用Redis图形化程序界面

Redis中默认有16个库,可以在不同的库中存储数据,默认使用0号库存储数据,使用select 0-15可以选择不同的库。

下载地址:GitHub - lework/RedisDesktopManager-Windows: RedisDesktopManager Windows版本

八 主从复制 (重要)

主从复制是指将一台Redis服务器的数据,复制到其它的Redis服务器。前者称为主节点(master),后者称为从节点(slave);数据的复制是单向的,只能由主节点到从节点。

默认情况下,每台Redis服务器都是主节点,且一个主节点可以有多个从节点(或没有从节点),但一个从节点只能有一个主节点。

主从复制的作用:

1.数据冗余:主从复制实现了数据的热备份,是持久化之外的一种数据冗余方式。

2.故障恢复:当主节点出现问题时,可以由从节点提供服务,实现快速的故障恢复,但实际上是一种服务的冗余.

3.负载均衡:在主从复制的基础上,配合读写分离,可以由主节点提供写服务,由从节点提供读服务(即写Redis数据时应用连接主节点,读Redis数据时应用连接从节点),分担服务器负载;尤其是在写少读多的场景下,通过多个从节点分担读负载,可以大大提高Redis服务器的并发量。

4.高可用基石:除了上述作用以外,主从复制还是哨兵和集群能够实施的基础,因此说主从复制是Redis高可用的基础.

配置步骤 在一台redis开三个

1.info replication查看主副机信息

2.关闭当前运行的redis,打开四个链接,进行测试,拷贝三个redis.conf文件(改成6379,6380,6381)

3.分别修改这三个文件信息,需要修改:端口,pid名字,log文件名字,dump.rdb名字

port 6379

pidfile /var/run/redis_6379.pid

logfile "6379.log"

dbfilename dump6379.rdb

port 6380

pidfile /var/run/redis_63780pid

logfile "6380.log"

dbfilename dump6380.rdb

port 6381

pidfile /var/run/redis_6381.pid

logfile "6381.log"

dbfilename dump6381.rdb

4.分别在三个链接中启动6379,6380,6381三台redis-server,在第四个链接中查看

5.配置一主二从

[root@localhost bin]# ./redis-cli -p 6380

127.0.0.1:6380> slaveof 127.0.0.1 6379

6.由于这里使用的是命令进行配置,所以是暂时的,一般公司配置会在配置文件中进行配置,属于永久性配置,相当于一打开当前服务器,该服务器就是从机,一般主机可以写,从机不能写只能读,主机中的所有信息和数据都会被从机保存!

从机可以使用命令:127.0.0.1:6380>slaveof no one 使自己成为主机

7.主从复制原理

Slave启动成功连接到master后会发送一个sync同步命令,Master接到命令后,会启动后台的存盘进程,同时收集所有接收到的用于修改数据集命令,在后台进程执行完毕后,master将传送整个数据文件到salve,并完成一次完整的同步.

全量复制:salve服务在接收到数据库文件数据后,将其存盘并加载到内存中.

增量复制:master继续将新的所有收集到的修改命令依次传递给salve,完成同步.

九 Redis 的哨兵模式

当主服务器宕机后,并且我们并没有及时发现,这时候就可能会出现数据丢失或程序无法运行。此时,redis的哨兵模式就派上用场了,可以用它来做redis的高可用.

每个哨兵都是监控主节点,主节点宕机,哨兵不会宕机!

功能作用:

1.监控(monitoring):Sentinel 会不断地检查你的主服务器和从服务器是否运作正常。

2.提醒(Notifation):当被监控的某个 Redis 服务器出现问题时, Sentinel 可以通过 API 向管理员或者其他应用程序发送通知。

3.自动故障转移(Automatic failover):当一个主服务器不能正常工作时, Sentinel 会开始一次自动故障迁移操作, 它会将失效主服务器的其中一个从服务器升级为新的主服务器, 并让失效主服务器的其他从服务器改为复制新的主服务器; 当客户端试图连接失效的主服务器时, 集群也会向客户端返回新主服务器的地址, 使得集群可以使用新主服务器代替失效服务器。

配置步骤

1.创建哨兵配置文件

[root@localhost bin]# vim sentinel.conf

sentinel.conf文件内容如下:(格式:sentinel monitor 被监控名称 host port 1)

sentinel monitor myredis 127.0.0.1 6379 1

2.启动哨兵

[root@localhost bin]# ./redis-sentinel sentinel.conf

3.如果Master节点断开了(主机宕机了),过一会,会发送哨兵日志,并自动通过算法在其他两个从机中选择一个成为主机.

优点

1.哨兵集群模式是基于主从模式的,所有主从的优点,哨兵模式同样具有。

2.主从可以切换,故障可以转移,系统可用性更好。

3.哨兵模式是主从模式的升级,系统更健壮,可用性更高。

缺点

1.Redis较难支持在线扩容,在集群容量达到上限时在线扩容会变得很复杂。

2.实现哨兵模式的配置也不简单,甚至可以说有些繁琐

redis缓存穿透 击穿,雪崩,倾斜

1.1 缓存穿透(查不到)

概念:当用户去查询数据的时候,发现redis内存数据库中没有,于是向持久层数据库查询,发现也没有,于是查询失败,当用户过多时,缓存都没有查到,于是都去查持久层数据库,这会给持久层数据库造成很大的压力,此时相当于出现了缓存穿透。

 

 

解决方案:

1.布隆过滤器:是一种数据结构,对所有可能查询的参数以hash形式存储,在控制层先进行校验,不符合则丢弃,从而避免了对底层存储系统的压力.

 2.缓存空对象:当存储层查不到时,即使返回的空对象也将其缓存起来,同时设置一个过期时间,之后再访问这个数据将会从缓存中获取,保护后端数据.

 

但会有两个问题:

1.如果空值被缓存起来,就意味着需要更多的空间存储更多的键,会有很多空值的键.

2.即使对空值设置了过期时间,还是会存在 缓存层和存储层会有一段时间窗口不一致,这对于需要保持一致性的业务会有影响.

1.2 缓存击穿(访问量大,缓存过期

指对某一个key的频繁访问,在不停的扛着大并发,大并发集中对这一个点进行访问,当这个key在失效的瞬间,持续的大并发就会直接请求数据库,就像在一个屏障上凿开了一个洞,例如微博由于某个热搜导致宕机.

其实就是:当某个key在过期的瞬间,有大量的请求并发访问,这类数据一段是热点数据,由于缓存过期,会同时访问数据库来查询最新数据,并回写缓存,导致数据库瞬间压力过大。

 

解决方案:

1.设置热点数据永不过期:从缓存层面上来说,不设置过期时间,就不会出现热点key过期后产生的问题.

2.添加互斥锁:使用分布式锁,保证对每个key同时只有一个线程去查询后端服务,其他线程没有获得分布式锁的权限,因此只需要等待即可,这种方式将高并发的压力转移到了分布式锁上,对分布式锁也是一种极大的考验.

1.3 缓存雪崩

指在某一个时间段,缓存集中过期失效或Redis宕机导致的,例如双十一抢购热门商品,这些商品都会放在缓存中,假设缓存时间为一个小时,一个小时之后,这些商品的缓存都过期了,访问压力瞬间都来到了数据库上,此时数据库会产生周期性的压力波峰,所有的请求都会到达存储层,存储层的调用量暴增,造成存储层挂掉的情况.

 

 

其实比较致命的缓存雪崩,是缓存服务器某个节点宕机或断网,因为自然形成的缓存雪崩,一定是在某个时间段集中创建缓存,此时的数据库还是可以顶住压力的,而缓存服务节点的宕机,对数据库服务器造成的压力是不可预知的,有可能瞬间就把服务器压垮.

解决方案:

1.配置Redis的高可用:其实就是搭建集群环境,有更多的备用机.

2.限流降级:在缓存失效后,通过加锁或者队列来控制读服务器以及写缓存的线程数量,比如对某个key只允许一个线程查询数据和写缓存,其他线程等待.

3.数据预热:在项目正式部署之前,把可能用的数据预先访问一边,这样可以把一些数据加载到缓存中,在即将发生大并发访问之前手动触发加载缓存中不同的key,设置不同的过期时间,让缓存失效的时间尽量均衡.

1.4 缓存倾斜

指某一台redis服务器压力过大而导致该服务器宕机.

 

八 最后一项

1.key的生存时间到了,Redis会立即删除吗?

不会立即删除

1.1定期删除:Redis每隔一段时间就去会去查看Redis设置了过期时间的key,会再100ms的间隔中默认查看3个key。

1.2惰性删除:如果当你去查询一个已经过了生存时间的key时,Redis会先查看当前key的生存时间,是否已经到了,直接删除当前key,并且给用户返回一个空值。

2.Redis的淘汰机制

在Redis内存已经满的时候,添加了一个新的数据,执行淘汰机制。(redis.conf中配置)

2.1 volatile-lru:在内存不足时,Redis会在设置过了生存时间的key中干掉一个最近最少使用的key。

2.2 allkeys-lru:在内存不足时,Redis会在全部的key中干掉一个最近最少使用的key。

2.3 volatile-lfu:在内存不足时,Redis会在设置过了生存时间的key中干掉一个最近最少频次使用的key。

2.4 allkeys-lfu:在内存不足时,Redis会在全部的key中干掉一个最近最少频次使用的key。

2.5 volatile-random:在内存不足时,Redis会在设置过了生存时间的key中随机干掉一个。

2.6 allkeys-random:在内存不足时,Redis会在全部的key中随机干掉一个。

2.7 volatile-ttl:在内存不足时,Redis会在设置过了生存时间的key中干掉一个剩余生存时间最少的key。

2.8 noeviction:(默认)在内存不足时,直接报错。

方案:指定淘汰机制的方式:maxmemory-policy具体策略,设置Redis的最大内存:maxmemory 字节大小

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值