Redis学习笔记

162 阅读12分钟

Redis

1.Redis 基础

1)传统的ACID

A(Atomicity)原子性
C(Consistency)一致性
I(Isolattion)独立性
D(Durability)持久性

2)CAP

C:Consistency(强一致性)
A:Availability(可用性)
P:Partition tolerance(分区容错性)

REmote DIctionary Server(远程字典服务器)

3)Redis 相关命令

  • redis 启动

    cd /usr/local/bin/
    redis-server /myredis/redis.conf
    redis-cil -p 6379
    
  • 关闭

    shutdown
    exit
    
  • 查看启动项

    ps -ef|grep redis
    
  • 测试工具: redis-benchmark

4)基础知识:

redis 默认有16个数据库 默认使用第0select 3 切换数据库
dbsize:查看Db大小
flushdb:清空当前数据库
flushAll:清空所有数据库
exists:判断key值是否存在
move :移除key
Expire key 10 :设置key过期的时间 单位是秒
ttl key :查看key剩余存在时间
type key :查看key的类型

Redis是单线程的:redis是将所有的数据全部放在内存中的,所以单线程操作就是效率最快的。

2.Redis数据结构

1)String

append key value : 拼接字符串
Strlen key : 查看value的长度
incr key : i++;
decr key : i--;
incrBy key value : 加固定值
decrBy key value :减固定值
getRange key 0 3 : 截取字符串从03
getRange key 0 -1 : 获取所有字符串
setRange key 1 value: 从字符串第一个开始替换value

setex(set with expire) 设置过期时间 
setex key 30 value :value 在30秒后过期
setnx(set if not exist) 不存在设置。
setnx key value :如果key不存在,创建可以
如果key存在,创建失败

mset k1 v1 k2 v2 k3 v3 :同时添加多个key
mget k1 k2 k3 :同时get多个key

msetnx:原子性操作。要么同时成功,要么同时失败。

127.0.0.1:6379> mset user:1:name zhangsan user:1:age 2
OK
127.0.0.1:6379> mget user:1:name user:1:age
1) "zhangsan"
2) "2"
设计key:user:{id}:{filed}

getset:先get再set 如果不存在值,则返回null
如果存在值,获取原来的值,并设置新值	

127.0.0.1:6379> getset db redis
(nil)
127.0.0.1:6379> get db
"redis"
127.0.0.1:6379> getset db mongdb
"redis"
127.0.0.1:6379> get db
"mongdb"

String 类似的使用场景value除了是字符串还可以是数字
计数器
统计多单位的数量
粉丝数
对象缓存存储

2)List

push
127.0.0.1:6379> LPUSH list one //将一个值插入列表的头部
(integer) 1
127.0.0.1:6379> lpush list two
(integer) 4
127.0.0.1:6379> lpush list therr
(integer) 5
127.0.0.1:6379> lrange 0 -1
127.0.0.1:6379> lrange list 0 -1
1) "therr"
4) "two"
5) "one"
127.0.0.1:6379> lrange list 0 1 //获取list的值
1) "therr"
2) "two"
127.0.0.1:6379> rpush list right////将一个值插入列表的尾部
127.0.0.1:6379> lrange list 0 -1
1) "therr"
2) "two"
3) "two"
4) "two"
5) "one"
6) "right"
pop
lpop list :移除左边第一个
lpop list :移除右边第一个
lindex:
lindex list 0:获取index的值
llen:
llen list :返回列表长度
lrem list count value :移除指定个数的值
ltrim list 1 2 : 通过小标指定的长度,list已经被改变
rpoplpush:移除列表最后的一个元素到新的列表中
rpoplpush list list1

lset list 0 value:更新值
exists list :判断列表是否存在。

linsert list (before/after) value newValue:将某一个具体的值插入到列表中某个元素的前面或后面。
  
小结:实际上是一个链表,可以当作队列LPush Rpop 栈LPush Lpop

3) set(集合)不能有重复元素

sadd set value 
smembers set :查看set元素
sismember set value:判断某一个值是不是在集合中
scard set :获取元素的值
srem set value:移除某一个元素
srandmember set  :随机取一个数
srandmember set 2 :随机取2个数
spop set :随机删除一个元素
smove set1 set2 value: 将一个指定的值,移动到另一个集合中
sdiff set1 set2:差集
sinter set1 set2 :并集
sunion set1 set2:交集

4)Hash(哈希)

map集合,key-map集合(本质和String类型没有太大的区别)
hset myhash key value :
hget myhash key :
hmset myhash k1 v1 k2 v2:设置多个key value 值
hmget myhash k1 k2:获取多个key
hgetall myhash:获取所有的可以:以键值队形式
hdel myhash k1 k2:删除指定的key
hlen myhash:获取hash表的字段长
hexists myhash key :判断hash中指定字段是否存中
hkeys myhash:获取所有的字段
hvals myhash:获取所有的value
hincrby myhash key count :指定的key的值增加count
hsetnx myhash key value :如果不存在则可以设置
hash应用:
hash变更的数据:用户信息的保存。更适合与对象的存储。

5)Zset(有序集合)

在set的基础上,增加了一个值,set k1 v1  zset k1 score1 v1
127.0.0.1:6379> zadd myset 1 one
(integer) 1
127.0.0.1:6379> zadd myset 2 two
(integer) 1
127.0.0.1:6379> zadd myset 3 three 4 fore
(integer) 2
127.0.0.1:6379> zrange myset 0 -1
1) "one"
2) "two"
3) "three"
4) "fore"
zrevrange key //从大到小
zrangebyScore key min max//从小到大
zrangebyScore salary -inf +inf withscores//显示全部的用户并且附带成绩
zrem salary key
zcard salary :获取有序集合的数量
zcount key start end : 计算对应区间的数据个数

6)Geospatial:地理位置 底层基于ZSET

geoadd:添加地理位置
	geoadd key 经度 维度 member

geopos :获取地理位置,坐标值

geodist:返回两个位置的距离
	geodist key member1 member2 单位
	
georadius:以给定的经纬度为中心,找出某一半径内的元素。
	georadius key 经度 维度 距离 单位 wistdist(带距离) wistcoord(经纬度) count(数量)
	
georadiusBymembers:找出指定元素周围的其他元素	
georadiusBymembers key member 距离 单位

geohash:将二维的经纬读转换为一维的字符串。

7)Hyperloglog:

pfadd:添加
pfcount:统计
pfmerge:合并两组

8)Bitmaps:位存储

setbit key offect value :存储
getbit key offect:获取
bitcount key :统计

3.Redis事务:

redis事务本质:一组命令的集合
一次性,顺序性,排他性
redis事务:
	1.开启事务(Multi)
	2.命令入队(....)
	3.执行事务(exec)
锁:redis可以实现乐观锁

放弃事务:discard  事务队列命令读不执行

(编译时错误)错误的命令:执行事务也会报错,所有的命令都不会执行

(执行时错误)事务队列中存中语法性的错误,执行命令的时候其他命令可以正常执行。
监控:Watch
	悲观锁:认为什么时候都会出问题,无论做什么都会加锁
	乐观锁:认为什么时候都不会出问题,不会加锁。

4.SpringBoot整合

jedis:采用的直连,多个线程操作的话是不安全的。
lettuce:采用netty,实例可以在多个线程共享。

5.redis.conf配置

配置文件的单位大小写不敏感

1)网络:

bind 127.0.0.1 绑定的ip
protected-mode yes
port 6379

2)通用GENERAL

daemonize yes #以守护进程的方式运行,默认是no,我们需要自己开启为yes。

pidfile /var/run/redis_6379.pid #如果后台方式运行,需要指定pid文件

loglevel notice :日记 

databases 16 :默认16个数据库数量

3)SNAPSHOTTING:快照

持久化,在规定的时间内,执行了多少次操作,则会持久化到文件rdb.aof
redis是内存数据库,没有持久化,那么数据断电即失去
//900秒内,如果至少有一个key进行了修改,就进行持久化操作。
save 900 1
//300秒内,如果至少有10个key进行了修改,就进行持久化操作。
save 300 10
//60秒内,如果至少有10000个key进行了修改,就进行持久化操作。
save 60 10000

stop-writes-on-bgsave-error yes//持久化出错,是否继续工作

rdbcompression yes//是否压缩rdb文件,需要消耗cpu资源。

rdbchecksum yes//保存rdb文件的时候,是否校验

dir ./ //rdb文件保存的目录

4)SECURITY:安全

可以在这里设置密码,
config get requirepass

config set requirepass 123456
//登录
auth 123456

5)APPEND ONLY MODE :aof

appendonly no:默认是不开启,默认使用Rdb方式持久化。

appendfilename "appendonly.aof" //持久化的文件名字

appendfsync always  // 每次修改都会执行

appendfsync everysec //每秒执行一次

appendfsync no 	//不执行,操作系统自己同步数据

6.Redis持久化:

1)RDB(redis DataBase)

触发机制:
1.save 的规则满足的情况下,会自动触发rdb规则
2.执行flushall命令,也会触发rdb规则
3.退出redis,也会触发rdb规则

如何恢复rdb文件
1.只需将rdb文件放在我们redis启动目录就可以,redis 就可自动检查dump.rdb恢复其中的数据
2.查看需要存中的位置
config get dir
优点:
	1.适合大规模的数据恢复!dump.rdb
	2.对数据的完整性不高,

缺点:
	1.需要一定的时间间隔,如果redis宕机了,最后一次修改的数据就没有了。
	2.fork进程的时候,会占用一定的内存空间

2)AOF(Append Only File)

将我们所有的命令记录下来,history,恢复的时候把这些文件全部执行一遍

 以日志的形式来记录每个写操作。
文件:appendonly.aof

appendonly.aof文件有错误,redis启动不起来。我们需要修复aof文件
redis-check-aof 修复工具。
redis-check-aof --fix
优点:
	1.每次修改都同步,文件完整性更好。
	2.每秒同步一次,可能会丢失一秒的数据
缺点:
	1.相对于数据文件,aof远远大于rdb,修复速度远比rdb慢
	2.Aof运行效率比rdb要慢,默认配置是rdb

重写规则:如果aof文件大于64M会fork一个新进程,来将文件重写

7.Redis发布订阅

第一个:消息发送者
第二个:频道
第三个:消息订阅者

命令:
subscribe channle 订阅频道

publish channle message 发布消息

unsubscribe channle

8.Redis主从复制

是指将一台redis服务器的数据,复制到其他的的redis服务器。前者称为主节点(master/leader), 后者成为从节点(slave/follower);数据的复制是单向的,只能由主节点到从节点。master以写为主, slave以读为主。

作用:
1.数据冗余:主从复制实现了数据的热备份,是持久化之外的一种数据冗余方式
2.故障恢复:当主节点出现问题时候,可以有从节点提供服务,实现快速的故障恢复,是服务的一种冗余
3.负载均衡:当主从复制的基础上,配合读写分离,可以有主节点提供服务,由从节点提供读服务。
4.高可用基石:主从复制是哨兵和集群能够实施的基础

主从复制,读写分离。

环境配置 只配置从库,不配置主库

info replication:查看当前库的信息

Replication

role:master 角色 connected_slaves:0 从机数量

修改配置文件:4个位置
1.port
2.pid
3.log
4.dump.rdb的名字

默认情况下每台redis都是主服务器。

认老大: slaveof ip port

真实的主从配置应该在文件中配置。

细节: 主机可以写,从机不能写只能读。主机中所有信息和数据都会自动被从机保存。

测试:主机断开连接,从机依旧连接到主机的,但是没有写操作。 主机如果回来了,从机依旧可以获得主机写的信息。

  如果命令行配置的主从,从机断了,再次连接会变成主机。只要变回从机,立马从主机中拿回数据。
  复制原理:slave启动成功连接到master后台会发送一个sync同步命令
			master接到命令,启动后台的存盘进程,同时收集所有接收到的用于修改数据的集合命令,
			后台执行完毕之后,master将传送整个数据文件到slave,并完成一次完全同步。
	
	全量复制:slave服务接到数据库文件数据之后,将其加载到内存中。
	增量复制:master继续新的所有收集到的修改命令依次传给slave

如果主机断开了连接,我们可以使用 slaveof no one ,让它变成主机。

9.哨兵模式(自动选举当老大)

主从切换技术的方法是:当主服务器宕机后,需要手动把一台从服务器切换为主服务器。造成一段时间内服务不可用 能够后台监控主机是否故障,如果故障了根据投票数自动将从库转换为主库

哨兵模式是一种特殊的模式,首先redis提供了哨兵的命令,哨兵是一个独立的进程,它独立运行。原理是哨兵通过发送命令,等待redis服务器响应,从而监控运行的多个redis实例。

哨兵作用:
	1.通过发送命令,让redis服务器返回监控其运行状态,包括服务器主服务器和从服务器。
	2.当哨兵监测到master宕机,会自动将slave切换成master,然后通过发布订阅模式通知其他从服务器
	  修改配置文件,让他们切换主机。

然后一个哨兵进程对redis服务器监控,可能会出现问题,为此,我们使用多个哨兵进行监控, 各个哨兵之间还会进行监控,这样就形成了多哨兵模式。

假设主服务器宕机,哨兵1先检测到这个结果,系统不会马上进行failover过程,仅仅是哨兵1主观的认为主服务器不可用,这个是主管下线。当后面的哨兵也检测到主服务器不可用,并且数量达到一定值时,那么哨兵之间会进行投票,投票的结果由一个哨兵发起,进行failover操作。切换成功后,就会通过发布订阅模式,让各个哨兵把自己监控的从服务器实现切换主机,这个过程称为客观下线。

配置哨兵配置文件
sentinel.conf

sentinel monitor myredis 127.0.0.1 6379 1

启动哨兵模式

redis-sentinel sentinel.conf

如果master节点断开了,这个时候就会从从机中随机选择一个服务器。 如果主机回来了,就只能归并到新的主机下,当作从机。

failover 故障转移

优点:
	1.哨兵集群,基于主从复制模式,
	2.主从可以切换,故障可以转移,系统的可用性会更好
	3.哨兵模式就是主从模式的升级,手动到自动,更加健壮。
缺点:
	1.redis不好在线扩容,集群容量一旦待到上限,在线扩容很麻烦。
	2.实现哨兵模式的配置很麻烦。

Redis缓存穿透和雪崩

缓存穿透:(查不到) 如果缓存中没有,这个时候就会去数据库中查询。

解决方案: 布隆过滤器:是一种数据结构,

缓存击穿:(量太大,缓存过期)

解决方案: 设置热点数据永不过期

互斥锁(分布式锁)

缓存雪崩:旨在一个时间段,缓存集中过期失效。