Redis学习笔记

一、Redis安装

我是使用docker安装的,首先在/usr/local/docker目录下创建redis目录

cd /usr/local/docker

mkdir redis,在redis目录下创建data目录和新建redis.conf文件

进入redis.conf文件,把在网上找到的redis配置文件复制进自己的文件

修改启动默认配置(从上至下依次):
bind 127.0.0.1 #注释掉这部分,这是限制redis只能本地访问
protected-mode no #默认yes,开启保护模式,限制为本地访问
daemonize no#默认no,改为yes意为以守护进程方式启动,可后台运行,除非kill进程,改为yes会使配置文件方式启动redis失败
databases 16 #数据库个数(可选),我修改了这个只是查看是否生效。。
dir ./ #输入本地redis数据库存放文件夹(可选)
appendonly yes #redis持久化(可选)
requirepass 密码 #配置redis访问密码

配置完成之后启动redis

docker run -p 6379:6379 --name demoredis --privileged=true -v /usr/local/docker/redis/redis.conf:/etc/redis/redis.conf -v /usr/local/docker/redis/data:/data -d redis redis-server /etc/redis/redis.conf --appendonly yes

docker ps查看redis是否启动成功,如果不成功则

docker logs demoredis 查看日志,处理问题后再次启动

进去redis客户端。 docker exec -it redis redis-cli

二、Redis基本操作

五大数据类型

1、String

String底层是动态字符串,可以类似StringBuffer

set key value        普通的存值,如果key相同会覆盖

get key        取值         

append key value        将value追加到key的末尾

strlen key        获取key的长度

setnx key value        加锁,没有key时才能成功

incr key        加一,只对数字类型有用

decr key        减一,只对数字类型有用

incrby key num        把key增加num

decrby key num        把key减少num

mset k1 v1 k2 v2 k3 v3        设置多个key,value

mget k1 k2 k3        取多个值

msetnx k1 v1 k2 v2 k3 v3        设置多个锁,只有所有key都不存在才成功

setex k1 timeout v1        设置值和过期时间timeout

2、List

底层是双向链表

lpush/rpush key v1 v2 v3        向左边/右边加入多个值

lpop/rpop key        从左边/右边拿出一个值,全部取出之后key消失

rpoplpush k1 k2        从k1右边拿出一个值插入k2左边

lrang key start end        从key中取一定范围的值,0表示左边第一个,-1表示右边第一个,0 -1表示取所有值

lindex key index        从key中取出该下标的值,从0开始

llen key        获取列表长度

linsert key before value newvalue        在值的后面加入新值

lrem key n value        删除n个值为value的数据

lset key index value        将下标值替换成value

3、set 

数据结构是dict字典,字典是用哈希表实现的

sadd key v1 v2 v3        将一个或多个元素加入到集合,重复的会忽略

smembers key        取出该集合所有值

sismember k1 v1        判断k1中是否有v1

scard key        集合中的个数

srem key v1 v2        删除集合中的值

spop key        随机从集合中取出一个值,会从集合删除

srandmember key n        随机取出n个值,不会从集合删除

sinter k1 k2        返回两集合的交集

sunion k1 k2        返回两集合的并集

sdiff k1 k2        返回两集合的差集

4、hash

对应的数据结构有两种,ziplist和哈希表,当field-value长度长时用哈希表

hset key field value        给key中的field属性赋值,可以多次给key添加属性

hget key field        从key中取出field的值

hmset key f1 v1 f2 v2        批量设置属性值

hexist key field        判断key中是否有该属性

hkeys key        查看key的所有属性

hvals key        查看key的所有属性值

hincrby key field n        给key的属性加n

5、zset有序集合

底层是hash和跳表

zadd key s1 v1 s2 v2 s3 v3        向key集合加入s评分和值,根据评分从小到大排序

zrange key start end        返回key集合的元素

zrangebyscore key s1 s2 withscores       返回评分s1到s2之间的值

zincrby key n value        给key集合的value加上n

zrem key value        删除指定值

zcount key s1 s2        返回key集合评分在s1到s2之间的个数

zrank key value        返回该值在key集合中的排名,从0开始

三、发布和订阅

redis发布订阅(pub/sub)是一种消息通信模式:发送者pub发送消息,订阅者sub接受消息

redis客户端可以订阅任意数量的频道

在Xshell6中打开两个页面,用于发布和订阅

cf423a35336d49559cfc31dbb60e5dfa.png

docker ps查看redis是否运行

docker exec -it demoredis /bin/bash进入目录

redis-cli开启一个客户端,先订阅一个频道

subscribe channel1
如果配置了密码,此处会报错 

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAc2h1YWlmZWlmZWlh,size_10,color_FFFFFF,t_70,g_se,x_16

 此时需要auth password(此处为你设置的密码)重新加载一下权限才能使用

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAc2h1YWlmZWlmZWlh,size_10,color_FFFFFF,t_70,g_se,x_16

此时redis客户端就已经订阅了channel1频道

另外一个客户端也是同样进入docker的redis目录

redis-cli

auth password(此处为你设置的密码)

publish channel1 hello        发布消息到channel1频道

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAc2h1YWlmZWlmZWlh,size_10,color_FFFFFF,t_70,g_se,x_16

 切回第一个redis客户端

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAc2h1YWlmZWlmZWlh,size_11,color_FFFFFF,t_70,g_se,x_16

成功接收到hello 

四、新数据类型

1、Bitmaps

bitmaps是专门进行位操作的字符串

setbit key offset value        设置key在某个偏移量上的值,只能为0 1

getbit key offset        获取key在该偏移量上的值

bitcount key        返回值被设置为1的个数

bitcount key start end        返回两参数之间值被设置为1的个数-1表示最后一位

bitop and(or/not/xor) destkey k1 k2        复合操作,and(交集),or(并集),not(非),xor(异或),并将结果保存在destkey中

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAc2h1YWlmZWlmZWlh,size_20,color_FFFFFF,t_70,g_se,x_16

 bitmaps更加节约内存

2、HyperLogLog

用于做基数(不重复元素)统计

pfadd key value        向key中加入数据,可以多次添加,数量加1,添加重复value不加1

pfcount key        返回key中的基数个数

pfmerge destkey k1 k2        将k1和k2合并到destkey中

3、Geospatial

用于存放经纬度 

 

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAc2h1YWlmZWlmZWlh,size_16,color_FFFFFF,t_70,g_se,x_16

geoadd key 经度 纬度 value         设置key中的value的经纬度

geopos key value        获取经纬度

geodist key v1 v2 km        获取两个地点之间的距离,单位位km(千米),单位有m(米),km(千米),mi(英里),ft(英尺),不设置默认为m

georadius key 经度 纬度 num km        取到key在该经纬度num千米内的值

五、Java中使用Redis

1、Jedis使用

1、准备工作

在pom文件中导入jedis依赖

<dependency>
    <groupId>redis.clients</groupId>
    <artifactId>jedis</artifactId>
    <version>4.1.1</version>
</dependency>

在springboot中测试jedis

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAc2h1YWlmZWlmZWlh,size_19,color_FFFFFF,t_70,g_se,x_16

 输入你虚拟机的ip和6379端口,虚拟机防火墙要开放此端口

firewall-cmd --add-port=6379/tcp --permanent

firewall-cmd --reload

并且在redis.conf配置文件中一定要注释bind 127.0.0.1,并且设置protected-mode no

如果设置了密码,还要在jedis中设置密码

jedis.auth("password");

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAc2h1YWlmZWlmZWlh,size_12,color_FFFFFF,t_70,g_se,x_16

 运行成功,控制台打印  PONG

2、java中使用Jedis

运行如果报错,检查redis是否能正常连接,key是否存在

1、key操作

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAc2h1YWlmZWlmZWlh,size_17,color_FFFFFF,t_70,g_se,x_16

 2、list操作

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAc2h1YWlmZWlmZWlh,size_17,color_FFFFFF,t_70,g_se,x_16

 3、set操作

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAc2h1YWlmZWlmZWlh,size_14,color_FFFFFF,t_70,g_se,x_16

 4、hash操作

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAc2h1YWlmZWlmZWlh,size_14,color_FFFFFF,t_70,g_se,x_16

 5、zset操作 

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAc2h1YWlmZWlmZWlh,size_18,color_FFFFFF,t_70,g_se,x_16

Jedis中的方法大多和Redis中一致,可以自己尝试

3、模拟验证码发送

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAc2h1YWlmZWlmZWlh,size_19,color_FFFFFF,t_70,g_se,x_16

 为了测试,代码都写在一起,基本流程如上,实际业务中需要修改

2、springboot整合redis

1、准备工作

在springboot的pom文件中导入依赖

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
    <version>2.6.3</version>
</dependency>
<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.13.1</version>
</dependency>

编写配置文件application.yml

spring:
  redis:
    #Redis服务器地址
    host: 192.168.81.130
    #Redis设置的密码
    password: 100940
    #Redis数据库索引(默认位0)
    database: 0
    #连接超时时间(毫秒)
    timeout: 1800000
    lettuce:
      pool:
        #连接池最大连接数(使用负值表示没有限制)
        max-active: 20
        #最大阻塞等待时间(负数表示没有限制)
        max-wait: -1
        #连接池中的最大空闲连接
        max-idle: 5
        #连接池中的最小空闲连接
        min-idle: 0

新增redis的配置类,配置redisTemplate

@EnableCaching //开启缓存
@Configuration
public class RedisConfig {
    @Bean
    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
        RedisTemplate<String, Object> template = new RedisTemplate<>();
        RedisSerializer<String> redisSerializer = new StringRedisSerializer();
        Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
        ObjectMapper objectMapper = new ObjectMapper();
        objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        objectMapper.activateDefaultTyping(LaissezFaireSubTypeValidator.instance, ObjectMapper.DefaultTyping.NON_FINAL, JsonTypeInfo.As.WRAPPER_ARRAY);
        jackson2JsonRedisSerializer.setObjectMapper(objectMapper);
        template.setConnectionFactory(factory);
        //key采用String的方式序列化
        template.setKeySerializer(redisSerializer);
        //value序列化方式采用jackson
        template.setValueSerializer(jackson2JsonRedisSerializer);
        //hash序列化方式采用jackson
        template.setHashValueSerializer(jackson2JsonRedisSerializer);
        return template;
    }
}

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAc2h1YWlmZWlmZWlh,size_20,color_FFFFFF,t_70,g_se,x_16

 创建controller类测试

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAc2h1YWlmZWlmZWlh,size_19,color_FFFFFF,t_70,g_se,x_16

 六、Redis的事务和锁机制

1、事务

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAc2h1YWlmZWlmZWlh,size_8,color_FFFFFF,t_70,g_se,x_16

multi指令,将接下来的操作放入队列中

exec指令,将队列中的操作执行

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAc2h1YWlmZWlmZWlh,size_8,color_FFFFFF,t_70,g_se,x_16

 discard指令,取消队列中的操作

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAc2h1YWlmZWlmZWlh,size_17,color_FFFFFF,t_70,g_se,x_16

组队期间报错,exec执行不成功 

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAc2h1YWlmZWlmZWlh,size_13,color_FFFFFF,t_70,g_se,x_16

 组队期间不报错,单条语句报错,其他语句执行,报错语句不执行

2、锁机制

watch key        加乐观锁,可以加多个key

乐观锁适用于多读的应用类型,这样可以提高吞吐量

3、模拟秒杀

yum install httpd-tools        下载ab工具

ab -n 1000 -c 100 http://192.168.1.91:8080/test        表示请求1000次,100个并发,ip为本机ip,不是虚拟机ip

七、Redis持久化

1、RDB

单独创建一个Fork进程来保存数据副本,等副本全部保存完成,才会替换到Redis中的dump.rdb文件,保证数据的完整性,RDB最后一次操作的数据可能会丢失

2、AOF

以日志的形式记录每个写操作,将Redis执行过的写指令记录下来,追加文件不允许改文件,AOF默认是不开启的,需要修改配置文件appendonly yes

AOF有文件自动修复功能

redis-check-aof --fix appendonly.aof        执行修复操作        

AOF和RDB同时开启,系统默认读取AOF数据

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAc2h1YWlmZWlmZWlh,size_17,color_FFFFFF,t_70,g_se,x_16

 八、Redis主从复制

读写分离,主机以写为主,从机以读为主

在linux中创建目录,/usr/local/docker/redis6380和/usr/local/docker/redis6381

分别在两个目录创建data文件夹和redis.conf配置文件,其中配置文件的端口号需要修改,masterauth需要添加

开启三个Redis,端口分别为6379,6380,6381

docker run -p 6380:6380 --name demoredis2 --privileged=true -v /usr/local/docker/redis6380/redis.conf:/etc/redis/redis.conf -v /usr/local/docker/redis6380/data:/data -d redis redis-server /etc/redis/redis.conf --appendonly yes

 

docker run -p 6381:6381 --name demoredis3 --privileged=true -v /usr/local/docker/redis6381/redis.conf:/etc/redis/redis.conf -v /usr/local/docker/redis6381/data:/data -d redis redis-server /etc/redis/redis.conf --appendonly yes

打开三个窗口分别连上不同端口的Redis

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAc2h1YWlmZWlmZWlh,size_20,color_FFFFFF,t_70,g_se,x_16

docker exec -it demoredis /bin/bash

docker exec -it demoredis2 /bin/bash

docker exec -it demoredis3 /bin/bash

redis-cli -p 6379 

redis-cli -p 6380

redis-cli -p 6381

info replication        查看主机运行情况

配从机不配主机

设置了密码需要在从机配置文件中修改masterauth选项

slaveof 192.168.81.130 6379

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAc2h1YWlmZWlmZWlh,size_13,color_FFFFFF,t_70,g_se,x_16

此时返回主机Redis查看,从机配置成功

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAc2h1YWlmZWlmZWlh,size_15,color_FFFFFF,t_70,g_se,x_16

主服务器挂掉,从服务器还是从服务器,重启之后还是变成他们的主服务器

从服务器挂掉,重启之后变回主机,需要重新slaveof配置从机

1、薪火相传

在从机中配置从机

slaveof 192.168.81.130 6380

除了从机的从机不是主机的从机外,其他的和一主多从一样

2、反客为主

slaveof no one

主机挂掉,从机会变成主机

3、哨兵模式

反客为主自动版

在redis文件夹的data文件夹中,新建sentinel.conf配置文件

在配置文件中复制以下内容

sentinel monitor mymaster 192.168.81.130 6379 1

其中mymaster为监控对象起的服务器名称,1为有一个哨兵同意迁移

进入docker的redis容器,运行以下命令

redis-sentinel sentinel.conf

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAc2h1YWlmZWlmZWlh,size_20,color_FFFFFF,t_70,g_se,x_16

九、Redis集群

当Redis存储不够,就需要水平扩容,即搭建集群

Redis3.0开始,提供了无中心化集群

任何一台服务器都可以作为入口,至少三个主节点

配置文件配置基本信息,其余的复制之后稍作修改

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAc2h1YWlmZWlmZWlh,size_16,color_FFFFFF,t_70,g_se,x_16

配置完后用docker启动这6个服务

将这6个节点配成集群

进入redis容器目录

redis-cli --cluster create --cluster-replicas 1 192.168.81.130:6379 192.168.81.130:6380 192.168.81.130:6381 192.168.81.130:6389 192.168.81.130:6390 192.168.81.130:6391

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAc2h1YWlmZWlmZWlh,size_20,color_FFFFFF,t_70,g_se,x_16

如果报错,在最后加上 -a password 

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAc2h1YWlmZWlmZWlh,size_20,color_FFFFFF,t_70,g_se,x_16

如果还报错,在最后加上 2>/dev/null 

如果没有反应,尝试把ip改成127.0.0.1

redis-cli -c -p 6379        -c表示采用集群策略连接,设置数据会自动切到相应的主机

cluster nodes        查看节点信息

slots插槽

Redis集群中有16384个插槽,会分配到集群中的Redis中

加入值是通过计算插槽位置来切换主机的,由于这个性质,不能用mset加入多个值

cluster keyslot key        查询key所在的插槽

cluster countkeysinslot slot        查看slot插槽里的数量,只能查看自己redis的插槽

故障恢复

Redis集群的故障恢复,主机挂了,从机成为主机,原来的主机恢复后成为从机

如果某一段插槽的主机和从机都挂了,在配置文件中有个配置

cluster-require-full-coverage

如果配置为yes,那么整个集群挂掉

如果为no,该段的插槽都不能操作,其他的可以操作

Jedis操作

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAc2h1YWlmZWlmZWlh,size_20,color_FFFFFF,t_70,g_se,x_16

 因为是无中心化集群,所以随便哪个节点都能作为入口

不能进行多键操作

十、常见问题

1、缓存穿透

redis命中率降低,一直查询数据库,造成数据库压力过大

出现大量恶意请求

解决方法:

1、对空值缓存,设置很短的过期时间

2、设置可访问白名单,名单存在bitmaps中

3、进行实时监控,排查访问对象,设置黑名单

4、限流

2、缓存击穿

Redis某个热点key正好过期,数据库访问压力瞬时变大

解决方法:

1、预先设置热门数据

2、实时调整热点key的时长

3、使用锁

3、缓存雪崩

缓存大面积失效

解决方法:

1、构建多级缓存架构:nginx缓存+redis缓存+其他缓存

2、使用锁或队列

3、设置过期标志,快过期更新缓存

4、将缓存失效时间分散开

十一、实现分布式锁

setnx key value        实现分布式锁

set key value  nx ex 60        实现分布式锁,同时设置60秒过期

del key        删除锁

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值