Redis入门,对Redis的理解和基本环境搭建及操作

Redis入门使用

参考:https://blog.csdn.net/hellozpc/article/details/81267030

一)、缓存的用途举例

1.前端页面广告的数据无需每次查询后台系统的接口 ,可以在前台系统添加缓存 ,提高访问首页的速度

2.电商网站首页左侧商品类目一栏的数据也可以缓存起来,不用每次打开首页都去数据库读取数据,读取数据库IO开销大。

二)、目前的缓存主流技术

  1. Redis

  2. Memcache

 区别:

 1. Memcache是多线程的,Redis是单线程的

 2. Memcache的缓存命中高

 3. Redis的功能强大

三)、什么叫缓存?

缓存的定义:把数据放在离计算机最近的地方以加快处理速度

CDN: 内容分发网络,距离终端用户最近的网络服务商,用户请求时最先到达CDN,CDN用于缓存网站的静态资源     (数据发生较少变化的资源),可以最快速度的返给用户

          如:视频网站、门户网站访问量大的热点内容

反向代理:应用于前端框架,反向代理服务器,缓存网站的静态资源,无需将请求分发给应用服务器就可以将数据 返还给用户

本地缓存:应用服务器本地缓存热点信息,应用程序在本机内存直接访问数据,无需访问数据库

分布式缓存:将数据专门的存在一个分布式集群中,应用程序通过网络通信访问数据

四)、使用缓存的条件

1. 数据被频繁访问

2. 数据在某段时间有效

五)、缓存的作用

1. 加快数据的访问速度

2. 减轻后端应用和数据存储的负载能力

六)、缓存的本质

 缓存的内存结构:缓存的内存结构是一张hash表,数据以key-value的形式存储

七)、缓存的读取

缓存用来存储读写比很高,很少改变的数据

如:商品类目信息,热门词的搜索列表信息,热门商品信息

当应用数据读取数据时,先到缓存中读取,缓存没有,再到数据库中读取,并将读取的数据放入缓存中

八)、Redis简介

Redis定义:

1. Redis是一个NoSql(not only sql:非关系系型数据库)数据库

2 .redis是Nosql数据库中 ,使用较为广泛的 ,非关系型内存数据库 

Redis的内部存储系统:

  1. Redis的内部存储系统是一个key-value存储系统

  2. 支持的value存储类型有:String,list, set, zset(sorted set:有序集合), hash(类似于java的map)

  3. Redis基于内存运行,并支持持久化

  4. Redis被称为数据结构存储服务器

九)、Redis的特性

(9-1)多种数据类型存储:

1.  字符串类型
2.  散列类型(hash:对应java的map类型)
3.  列表类型
4.  集合类型
5.  有序集合类型

(9-2)内存存储与持久化:

1. 内存的读写远快于硬盘
2. 自身提供持久化功能(RDB,AOF两种方式)

(9-3)功能丰富:

1. 可用做缓存、消息队列、消息订阅/发布
2. 支持键的生成时间
3. 按照一定的规则删除键

(9-4)简单稳定:

1. 相比Sql而言更简单
2. 不同语言客户端丰富
3. 基于C语言开发

十)、Redis与其他NoSql数据库的区别

1.有着更为复杂的数据结构 并且提供对他们的原子性操作 

2.数据类型都是基于基本数据结构,对程序员透明,无需进行额外的抽象 

3.Redis运行在内存中 ,可以持久化到磁盘 

4.对不同数据集进行高速读写时需要权衡内存,数据量不能大于硬件内存  

5.相比在磁盘上相同的复杂的数据结构 ,内存中操作起来非常简单 

6.磁盘格式方面 是紧凑的 ,以追加的方式产生的 ,不需要进行随机访问 

十一)、Redis的命令

Keys patteren : 获取符合所有patteren规则的键

匹配字符:?:匹配一个字符 *:匹配多个字符 []:

Keys * :获取所有的键

exists key : 判断键是否存在 ,存在,返回1, 不存在,返回0

del key [key] : 删除一个或多个键,返回删除键的个数

Type key:获取键对应的值的类型, 返回的可能是String, list, set, zset,hash

十二)、Redis的数据类型

1)、字符串类型

      set key value / get key : 设置键和值 / 获取键所对应的值

      incr num :  让当前键num的值递增,并返回递增后的键值

      incrby num 递增的步数: 让当前键num的值递增并设置每一次递增的步数

      decr num : 递减

    decrby num 递减步数: 按指定步数对键值递减

    append key value : 在指定的键值后添加数据

    strlen key:获取键值的长度

    mset key1 value1 key2 value2 : 设置多个键值对

    mget key1 key2 : 获取多个键对应的值



2)、列表类型List



    1.Redis列表是字符串列表 ,按插入顺序排序 

    2.可以添加一个元素到列表的头部(左边)或者尾部(右边)

    3.一个列表最多可以包含 2³²- 1 个元素   (4294967295, 每个列表超过40亿个元素) 

    blpop key1 [key2 ] timeout:  移出并获取列表的第一个元素, 如果列表没有元素会阻塞列表直到等待超时或发现可弹出元素为止。

    brpop key1 [key2 ] timeout:  移出并获取列表的最后一个元素, 如果列表没有元素会阻塞列表直到等待超时或发现可弹出元素为止  

    brpoplpush source destination timeout:  从列表中弹出一个值,将弹出的元素插入到另外一个列表中并返回它; 如果列表没有元素会阻塞列表直到等待超时或发现可弹出元素为止 

    lindex key index:  通过索引获取列表中的元素

    linsert key before|after pivot value: 在列表的元素前或者后插入元素  

    llen key:  获取列表长度 

    lpop key:  移出并获取列表的第一个元素 

    lpush key value1 [value2]:  将一个或多个值插入到列表头部 

    lpushx key value: 将一个值插入到已存在的列表头部 

    lrange key start stop:  获取列表指定范围内的元素 

    lerm key count value : 移除列表元素 

    lset key index value:  通过索引设置列表元素的值 

    ltirm key start stop:  对一个列表进行修剪(trim),就是说,让列表只保留指定区间内的元素,不在指定区间之内的元素都将被删除。

    rpop key : 移除并获取列表最后一个元素  

    rpoplpush source destination 移除列表的最后一个元素,并将该元素添加到另一个列表并返回 

    rpush key value1 [value2] :  在列表中添加一个或多个值 

    rpushx key value 为已存在的列表添加值 

3)、Set集合

    1.Redis的Set是string类型的无序集合 

    2.集合成员唯一 

    3.Redis 中 集合通过哈希表实现 

    4.一个集合最多可以包含 2³²- 1 个元素   (4294967295, 每个列表超过40亿个元素) 



    sadd key member1 [member2] : 向集合添加一个或多个成员 

    scard key:  获取集合的成员数 

    sdiff key1 [key2] : 返回给定所有集合的差集 

    sdiffstore destination key1 [key2]:  返回给定所有集合的差集并存储在 destination 中

    sinter key1 [key2] : 返回给定所有集合的交集  

    sinterstore destination key1 [key2] : 返回给定所有集合的交集并存储在 destination 中

    sismember key member:  判断 member 元素是否是集合 key 的成员  

    smember key:  返回集合中的所有成员 

    smove source destination member:  将 member 元素从 source 集合移动到 destination 集合 

    spop key: 移除并返回集合中的一个随机元素 

    srandmember key [count]: 返回集合中一个或多个随机数 

    srem key member1 [member2]:  移除集合中一个或多个成员 

    sunion key1 [key2] : 返回所有给定集合的并集

    sunionstore destination key1 [key2]:  所有给定集合的并集存储在 destination 集合中 

    sscan key cursorMATCH pattern[COUNT count] 迭代集合中的元素 

4)、有序集合(sorted -set)

1.有序集合和集合一样也是string类型元素的集合,且不允许重复的成员 

2.每个元素都会关联一个double类型的分数 ,通过分数来为集合中的成员进行从小到大的排序 

3.有序集合的成员是唯一的,但分数(score)却可以重复 

4.集合中最大的成员数为 2³²- 1  (4294967295, 每个集合可存储40多亿个成员)。 



    zadd key score1 member1 [score2 member2]:  向有序集合添加一个或多个成员,或者更新已存在成员的分数 

    zcard key : 获取有序集合的成员数 

    zcount key min max 计算在有序集合中指定区间分数的成员数 

    zincrby key increment member 有序集合中对指定成员的分数加上增量 increment 

    zinterstore destination numkeys key [key …]:  计算给定的一个或多个有序集的交集并将结果集存储在新的有序集合 key 中 

    zlexcount key min max 在有序集合中计算指定字典区间内成员数量 

    zrange key start stop [WITHSCORES] : 通过索引区间返回有序集合成指定区间内的成员 

    zrangebylex key min max [LIMIT offset count]:  通过字典区间返回有序集合的成员

     zrangebyscore key min max WITHSCORES:  通过分数返回有序集合指定区间内的成员 

    zrank key member:  返回有序集合中指定成员的索引  key member 返回有序集合中指定成员的索引 

    zrem key member [member …]:  移除有序集合中的一个或多个成员 

    zremrangebylex key min max: 移除有序集合中给定的字典区间的所有成员 

    zremrangebyrank key start stop:  移除有序集合中给定的排名区间的所有成员 

    remrangebyscore key min max :  移除有序集合中给定的分数区间的所有成员 

    zrevrange key start stop [WITHSCORES] : 返回有序集中指定区间内的成员,通过索引,分数从高到底 

    zrevrangebyscore key max min [WITHSCORES]:  返回有序集中指定分数区间内的成员,分数从高到低排序 

    zrevrange key member:  返回有序集合中指定成员的排名,有序集成员按分数值递减(从大到小)排序 

    zscore key member:  返回有序集中,成员的分数值 

    zunionstore destination numkeys key [key …] : 计算给定的一个或多个有序集的并集,并存储在新的 key 中 

    zscan key cursor MATCH pattern 迭代有序集合中的元素(包括元素成员和元素分值) 

5)、hash数据结构

  1.是一个string类型的field和value的映射表 

  2.特别适合用于存储对象 

  3.每个 hash 可以存储  2³²- 1 键值对(40多亿 )

    Map<String,Map<String,String>> 



    hdel key field2:  [field2] 删除一个或多个哈希表字段

    hexists key field:  查看哈希表 key 中,指定的字段是否存在 

    hget key field:  获取存储在哈希表中指定字段的值。 

    hgetall key:  获取在哈希表中指定 key 的所有字段和值 

    hincrby key field increment 为哈希表 key 中的指定字段的整数值加上增量 increment 

    hincrbyfloat key field increment 为哈希表 key 中的指定字段的浮点数值加上增量 increment 

    hkeys key : 获取所有哈希表中的字段  

    hlen key:  获取哈希表中字段的数量  

    hmget key field1 [field2]:  获取所有给定字段的值 

    hmset key field1 value1 [field2 value2 ] : 同时将多个 field-value (域-值)对设置到哈希表 key 中

    hset key field value:  将哈希表 key 中的字段 field 的值设为 value 

    hsettnx key field value:  只有在字段 field 不存在时,设置哈希表字段的值

    hvals key:  获取哈希表中所有值  

    hscan key cursor MATCH pattern : 迭代哈希表中的键值对。 

十三)、Redis的事物

1.Redis 事务可以一次执行多个命令 

2.事务是一个单独的隔离操作,事务中的所有命令都会序列化、按顺序地执行  

3.事务在执行的过程中,不会被其他客户端发送来的命令请求所打断 

4.事物是一个原子操作,事务中的命令要么全部被执行,要么全部都不执行

一个事务从开始到执行会经历以下三个阶段 :

    -: 开始事务  multi
    -: 命令入队  数据操作
    - :执行事务  exec

十四)、Redis事物的命令

discard:  取消事务,放弃执行事务块内的所有命令

exec:  执行所有事务块内的命令 

multi:  标记一个事务块的开始

unwatch: 取消 WATCH 命令对所有 key 的监视 

watch key [key …] 监视一个(或多个) key ,如果在事务执行之前这个(或这些) key 被其他命令所改动,那么事务将被打断 

十五)、Jedis的使用

简单示例:

导入pom.xml的jar包依赖

jedis:

//创建jedis对象
Jedis jedis = new Jedis("Redis服务器的地址","服务器的端口号")
//通过Jedis对象向Redis服务器发送数据
jedis.set("name","张三");
//通过Jedis向Redis服务器获取数据
jedis.get("name");

连接池的使用

//连接池的配置
JedisPoolComfig jedisPollConfig = new JedisPoolConfig();
//设置连接池的最大连接数量
jedisPollConfig.setMaxTotal(50);
//创建连接池
JedisPool jedisPool = new JedisPool(jedisPoolConfig,"Redis服务器地址","Redis服务器的端口号");
//获取连接池的连接
Jedis jedis = jedisPoll.getResource();
//读取数据
jedis.get("name");
//将连接返回连接池
jedisPoll.returnResource(jedis);

分片式集群

集群式连接池

//连接池的配置
JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
//设置连接池最大连接量
jedisPoolConfig.setMacTotal(50);
//定义集群信息
List<JedisShardInfo> shards = new ArrayList<JedisShardInfo>();
shards.add(new JedisShardInfo("redis服务器1地址","Redis服务器1端口号"));
shards.add(new JedisShardInfo("Redis服务器2地址","Redis服务器2端口号"));
//定义集群连接池
ShardJedisPool shardJedisPool = new ShardJedisPool(jedisPoolConfig,shards);
//从连接池中获取分片
ShardJedis shardJedis = shardJedisPool.getResource();
//获取数据
shard.get("name");

十六)、SpringBoot集成Redis

1.加入redis依赖的jar包

spring-boot-starter-data-redis

2.新增配置文件

# REDIS (RedisProperties)
# Redis数据库索引(默认为0)
spring.redis.database=0
# Redis服务器地址
spring.redis.host=localhost
# Redis服务器连接端口
spring.redis.port=6379
# Redis服务器连接密码(默认为空)
spring.redis.password=
# 连接池最大连接数(使用负值表示没有限制)
spring.redis.pool.max-active=8
# 连接池最大阻塞等待时间(使用负值表示没有限制)
spring.redis.pool.max-wait=-1
# 连接池中的最大空闲连接
spring.redis.pool.max-idle=8
# 连接池中的最小空闲连接
spring.redis.pool.min-idle=0
# 连接超时时间(毫秒)
spring.redis.timeout=0

十七)、Redis的实现

参考:https://www.jianshu.com/p/56999f2b8e3b

为什么使用Redis?

使用数据库来进行数据的存储会出现的问题:

使用数据库来保存数据的系统面向磁盘, 当系统的访问出现高并发的情况,涉及大批量的数据需求时,如商品抢购 ,或者是主页访问量瞬间较大的时候 ,磁盘读/写速度比较慢 ,一瞬间成千上万的请求到来 ,系统不能在极短的时间内完成成千上万次的读/写操作 ,极其容易造成数据库系统瘫痪,最终导致服务宕机 。

Redis的性能:

1.支持每秒十几万次的读/写操作

2.支持集群、分布式、主从同步等配置 

 3.则上可以无限扩展,让更多的数据存储在内存中 

4.支持一定的事务能力,证了高并发的场景下数据的安全和一致性  

十八)、Redis 在 Java Web 中的应用

1.存储 缓存 用的数据

2.需要高速读/写的场合使用它快速读/写

Spring Data Redis的四种工厂模型

  • JredisConnectionFactory
  • JedisConnectionFactory
  • LettuceConnectionFactory
  • SrpConnectionFactory

十九)、配置RedisTemplate

RedisTemplate的作用:

Redis 只能支持六种数据类型(string/hash/list/set/zset/hyperloglog)的操作 ,Java 中我们却通常以类对象为主,使用RedisTemplate ,完成对象的转换。

RedisTemplate的实现机制:

将数据存入Redis

将对象序列化 ----- 》存入Redis

取出Redis的数据

转换器 ----- >对象
序列化和转换由RedisTemplate来实现

按原理来说如果要实现RedisTemplate的序列化和转换器的功能就需要配置独的序列化器去支撑这一步的工作,如果POJO类实现了Serializable接口,可以直接省略掉了配置序列化器

二十)、基于redis的API接口幂等设计

参考:https://blog.csdn.net/hellozpc/article/details/81347765

为什么要做redis的API接口幂设计?

1. 网络超时、手动刷新等,导致客户端重复提交数据到服务端  ,要求在设计API接口时做好幂等控制 。

2. 面向微服务架构的系统中 ,系统间的调用非常频繁 ,不做好幂等性设置,轻则会导致脏数据入库 

3. 基于Redis实现一个幂等控制框架,调用接口时传入全局唯一的token字段  ,标识一个请求是否是重复请求 

基于Redis实现一个幂等控制框架的思路:

1. 调用接口前先调用获取token的接口 ,成对应的令牌(token) ,存放在redis当中 

2. 调用接口时 ,将token放入请求头 

3. 解析请求头 ,如果能获取到该令牌,就放行,执行既定的业务逻辑,并从redis中删除该token 

4. 如果获取不到该令牌,就返回错误信息
金麟岂能忍一世平凡 飞上了青天 天下还依然
原文地址:https://www.cnblogs.com/Auge/p/11609791.html