Redis入门教程详解


Posted in Redis onAugust 30, 2021

Redis

Redis是一个开源(BSD许可)的内存数据结构存储,用作数据库、缓存和消息代理。Redis提供数据结构,如strings, hashes, lists, sets, sorted sets with range queries, bitmaps, hyperloglogs, geospatial indexes, and streams.。Redis具有内置复制、Lua脚本、LRU eviction、事务和不同级别的磁盘持久性,并通过Redis Sentinel和Redis Cluster的自动分区提供高可用性。

一、Redis基本数据结构

1. 字符串 (String)

字符串类型是Redis中最为基础的数据存储类型,它在Redis中是二进制安全的,这意味着该类型可以接受任何格式的数据,如JPEG图像数据或json对象描述信息等。在Redis中字符串类型的value最多可以容纳的数据长度是512M。

常用命令:

  • set key value 设置值
  • get key 获取值
  • getset 将给定的值设置进去,并返回旧值
  • mget key1 key2... 获取一个或多个key的值
  • setnx key value 当key不存在时才设置值
  • incr key 将key存储的值+1
  • incrby key increment 将 key 所储存的值加上给定的增量值(increment)
  • decr key 将key存储的值-1
  • decrby key increment 将 key 所储存的值减去给定的增量值(increment)
  • strlen key 返回key所存储的字符串的长度

注意:

1.字符串append命令会使用更多的内存

2.整数共享:如果能使用整数,就尽量使用整数

3.整数精度问题:redis能保证16位精度,17-18位的大整数就会丢失精度

2. 散列(hash)

Redis中Hash类型可以看成句又String key和String value的map容器。所以该类型非常适合存储对象的信息。

常用命令:

  • hset key field value
  • hget key field
  • hmset key field1 value1 [field2 value2 ] 同时set多个field值
  • hmget key field1 [field2]
  • hgetall key 获取key的所有值
  • hincrby key field increment 给指定的key的field增加给定的增量值(increment)
  • hkeys key 获取某个key的所有field
  • hvals key 获取某个key的所有value
  • hlen key 获取hash表中字段的数量
  • hexists key field 查看hash表中的字段是否存在
  • hdel key field1 [field2] 删除一个或多个hash表字段

3. 列表(list)

在Redis中,List类型是按照插入顺序排序的字符串链表。和数据库结构中的普通链表一样,可以在头部和尾部添加新的元素。在插入时如果键不存在,Redis将为该键创建一个新的链表。与此相反,如果链表中所有的元素均被移除,那么该键也会被从数据库中删除。

常用命令:

  • lpush key value1 [value2] 将一个值或多个值插入到列表头部
  • rpush key value1 [value2] 将一个值或多个值插入到列表尾部
  • lrange key start stop 获取列表指定范围的元素
  • lpop key 移出并获取列表中的第一个元素
  • rpop key 移出并获取列表中的最后一个元素
  • blpop key1 [key2 ] timeout 阻塞性的移出并获取列表的第一个元素,如果没有元素就会阻塞到超时或有元素为止
  • brpop key1 [key2 ] timeout 阻塞性的移出并获取列表的最后一个元素,如果没有元素就会阻塞到超时或有元素为止
  • lindex key index 通过索引位置获取列表中的元素
  • llen key 获取列表长度
  • lset key index value 通过索引位置设置值
  • ltrim key start stop 对一个列表进行修剪,只保留指定区间的元素,区间外的都删除掉

4. 集合(Set)

Redis 的 Set 是 String 类型的无序集合。集合成员是唯一的,这就意味着集合中不能出现重复的数据。Redis 中集合是通过哈希表实现的,所以添加,删除,查找的复杂度都是 O(1)。集合中最大的成员数为 2^32 - 1

常用命令:

  • sadd key member1 [member2] 向集合中添加元素
  • scard key 获取集合的成员数
  • sdiff key1 [key2] 返回第一个集合与其他集合之间的差异
  • sinter key1 [key2] 返回给定所有集合的交集
  • sunion key1 [key2] 返回给定集合的并集
  • sismember key member 判断member元素是否是集合中的成员
  • smembers key 返回集合中所有成员
  • spop key 移除并返回集中中的一个随机元素
  • srandmember key [count] 返回集合中一个或多个随机数
  • srem key member1 [member2] 移除集合中一个或多个成员

5. 有序集合(sorted set)

Redis 有序集合和集合一样也是 string 类型元素的集合,且不允许重复的成员。不同的是每个元素都会关联一个 double 类型的分数。redis 正是通过分数来为集合中的成员进行从小到大的排序。

常用命令:

  • zadd key score1 member1 [score2 member2] 向有序集合中添加一个或多个成员,或更新已有成员的分数
  • zcard key 获取有序集合中的成员数量
  • zrange key start end [withscores] 通过索引区间返回有序集合中的成员
  • zrevrange key start stop [WITHSCORES] 通过索引区间返回有序集合中的成员,分数从高到低
  • zrangebyscore key min max [WITHSCORES] [LIMIT] 通过分数返回有序集合指定区间内的成员
  • zrevrangebyscore key min max [WITHSCORES] [LIMIT] 通过分数返回有序集合指定区间内的成员,分数由高到低排序
  • zrem key member [member ...] 移除
  • zremrangebyrank key start stop 移除给定排名区间的所有成员
  • zremrangebyscore key min max 移除给定分数区间的所有成员
  • zscore key member 返回有序集合中成员的分数

二、Redis的高级数据结构

1. HyperLogLog

Redis 在 2.8.9 版本添加了 HyperLogLog 结构。Redis HyperLogLog是用来做基数统计的算法,HyperLogLog的优点是,在输入元素的数量或者体积非常非常大时,计算基数所需的空间总是固定 的、并且是很小的。不过这个是估算,有一定的误差。

基数计算指的是统计一批元素中不重复元素的个数,比如UV的统计。实现基数统计最常见的是用Set这种数据结构。但是大数据量下Set会占用很大的存储空间。

常用命令:

  • pfadd key element [element ...] 添加指定元素到HyperLogLog 中
  • pfcount key [key ...] 返回给定key的基数估算值
  • pfmerge destkey sourcekey [sourcekey ...] 将多个hyperloglog 合为一个

2. GEO

Redis GEO主要用于存储地理位置信息,并对其进行操作。该功能在Redis3.2版本增加

常用命令:

  • geoadd key longitude latitude member [longitude latitude member ...] 添加地理位置坐标
  • geopos key member [member ...] 返回指定member的经纬度
  • geodist key member1 member2 [m|km|ft|mi] 计算两个位置的距离 后面的是单位

m【米】 km【千米】 ft【英尺】 mi【英里】

  • georadius key longitude latitude radius m|km|ft|mi [WITHCOORD] [WITHDIST] [WITHHASH] [COUNT count] [ASC|DESC] [STORE key] [STOREDIST key] 以给定的经纬度为中心,返回键包含的元素中,与中心距离不超过给定最大距离的所有位置元素
  • georadiusbymember key member radius m|km|ft|mi [WITHCOORD] [WITHDIST] [WITHHASH] [COUNT count] [ASC|DESC] [STORE key] [STOREDIST key] 同上,只不过中心位置的传参由经纬度变成了member
  • geohash key member [member ...] 获取一个或多个元素的geohash值

3. BitMap

BitMap的原理上一篇已经讲过了,它可以用作大数据量的存储,不过存储的内容只能是0或1. 可以使用在10亿用户的在线状态,1代表在线,0代表离线。

value值只能是0、1

  • setbit key offset value
  • getbit key offset
  • bitcount key 获取值为1的个数

三、Redis 高级特性

1. Redis事务

Redis的事务与数据库的事务概念不同,Redis会将一个事务中的所有命令序列化,然后按顺序执行。Redis不可能在一个Redis事务的执行过程中插入执行另一个客户端发出的请求,事务中任意命令失败不影响其他命令的执行,也不会回滚。

2. 发布订阅

发布订阅是一种通信模式,发送者发送消息,订阅者接受消息。客户端可以订阅多个频道,然后有新消息发送给频道,订阅该频道的客户端就都能收到消息。

Redis入门教程详解

常用命令:

  • subscribe channel [channel ...] 订阅一个或多个频道
  • psubscribe pattern [pattern ...] 订阅一个或多个符合给定模式的频道
  • publish channel message 将消息发送到指定通道
  • unsubscribe [channel [channel ...]] 退订给定的频道
  • punsubscribe channel [channel ...] 退订所有给定模式的频道。

3. 脚本

Redis 脚本通过Lua解释器来执行脚本,Redis 2.6 版本通过内嵌支持Lua环境

基本语法如下:
EVAL script numkeys key [key ...] arg [arg ...]

例子:

EVAL "return {KEYS[1],KEYS[2],ARGV[1],ARGV[2]}" 2 key1 key2 first second

4. Redis Stream

Redis Stream是5.0版本新增的数据结构。Redis Stream主要用于消息队列,Redis本身有一个发布/订阅功能,但是它有一个缺点,消息没有持久化,如果网络中断或宕机,数据就会丢失。

Redis Stream提供了消息的持久化和主备复制功能,它有一个消息链表,把所有加入的消息都串起来,每个消息都有唯一的ID和内容。

常用命令:

  • xadd key ID field value [field value ...] 添加消息

xadd mystream * name sa surname occc (*代表id由redis生成)

  • xdel key ID [ID ..] 删除消息
  • xrange key start end [COUNT count] 查看消息

xrange mystream - + (- 代表最小值,+ 代表最大值)

  • xgroup [CREATE key groupname id-or-$] [SETID key groupname id-or-$] [DESTROY key groupname] [DELCONSUMER key groupname consumername] 创建消费者组

从头开始消费:

xgroup create mystream consumer-group-name 0-0

从尾部开始消费,只接受新消息

xgroup create mystream consumer-group-name $

  • xreadgroup group group consumer [COUNT count] [BLOCK milliseconds] [NOACK] STREAMS key [key ...] ID [ID ...] 从消费者组读取消息

XREADGROUP GROUP consumer-group-name consumer-name COUNT 1 STREAMS mystream

第二个group :消费组名
consumer: 消费者名
count :读取数量
milliseconds : 阻塞毫秒数
key :队列名
ID:消息id

四、Redis使用场景

1. 业务数据缓存

1.通用数据缓存:String、list

2.等会话缓存、token、session缓存

2. 业务数据处理

1.非严格一致性要求的数据

2.业务操作去重:订单处理的幂等校验业务数据排序

3. 全局一致计数

1.全局流控

2.秒杀时库存计算

3.全局ID生成

4. 高效统计计数

1.id、ip等使用bitmap操作

2.使用HyperLogLog进行UV、PV等非精确性的统计

5. 发布订阅与Stream

用于消息发布订阅模式

6. 分布式锁

1.获取锁

set key my_random_value NX PX 30000

2.释放锁,需要用到lua脚本保证原子性

if redis.call("get",KEYS[1])==ARGV[1] then
   return redis.call("del",KEYS[1])
else
  return 0
end

五、Redis的Java客户端

1. Jedis

基于BIO、线程不安全,需要配置连接池管理连接

2. Lettuce

目前主流推荐的驱动,基于Netty NIO,API线程安全

3. Redission

基于Netty NIO,API线程安全。大量丰富的分布式功能,如分布式的基本数据类型和锁。

六、项目集成

1. SpringMvc项目可以引入Spring data redis

maven依赖

<dependency>
            <groupId>org.springframework.data</groupId>
            <artifactId>spring-data-redis</artifactId>
            <version>2.1.2.RELEASE</version>
</dependency>

核心是RedisTemplate(可以配置基于Jedis、Lettuce、Redisson),封装了基本的redis命令。

2. SpringBoot接入(默认使用的Lettuce)

<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>

配置spring.redis

如:spring.redis.host=127.0.0.1

3. Spring Cache 集成Redis

1.启用Spring Cache

@EnableCaching

2.方法上添加缓存注解

@Override
    @Cacheable(value = "userCache")
    public User getUser(Integer id) {
        return userMapper.getUser(id);
    }

3.配置redisCache

@Configuration
public class CacheConfig {

    @Bean
    public RedisCacheManager cacheManager(RedisConnectionFactory redisConnectionFactory) {
        return RedisCacheManager.create(redisConnectionFactory);
    }
}

番外:

1.Redis到底是单线程,还是多线程?

这个问题有坑。首先Redis作为一个进程来讲是多个线程的。比如Redis通过多线程方式在后台删除对象、以及通过 Redis模块实现的阻塞命令等.单线程的地方在于探测哪个接收完了请求数据->数据处理->返回数据。而其他耗时操作是用了其他线程。

探测哪个客户端的请求接受完了,使用的是IO多路复用模型,“多路”是指多个网络连接,“复用”是复用同一个线程。

Redis入门教程详解

2.为什么IO模块在Redis6之前是单线程?

因为Redis是基于内存的操作,CPU不是瓶颈,瓶颈在于机器内存的大小或网络带宽。
3. Redis6之后的多线程是什么?

IO模型使用了多线程的NIO模型,内存处理线程也还是单线程。

Redis入门教程详解

以上就是Redis详解的详细内容,更多关于Redis的资料请关注三水点靠木其它相关文章!

Redis 相关文章推荐
Redis IP地址的绑定的实现
May 08 Redis
浅谈Redis的几个过期策略
May 27 Redis
详解Redis集群搭建的三种方式
May 31 Redis
深入理解redis中multi与pipeline
Jun 02 Redis
redis客户端实现高可用读写分离的方式详解
Jul 04 Redis
redis 存储对象的方法对比分析
Aug 02 Redis
分布式Redis Cluster集群搭建与Redis基本用法
Feb 24 Redis
解决linux下redis数据库overcommit_memory问题
Feb 24 Redis
分布式架构Redis中有哪些数据结构及底层实现原理
Mar 13 Redis
使用Redis做预定库存缓存功能
Apr 02 Redis
使用Redis实现分布式锁的方法
Jun 16 Redis
浅谈Redis变慢的原因及排查方法
Jun 21 Redis
Redis如何实现分布式锁
Aug 23 #Redis
Redisson实现Redis分布式锁的几种方式
Redis分布式锁Redlock的实现
Aug 07 #Redis
关于redisson缓存序列化几枚大坑说明
Aug 04 #Redis
Redis Cluster 集群搭建你会吗
Aug 04 #Redis
解析redis hash应用场景和常用命令
Aug 04 #Redis
redis 存储对象的方法对比分析
Aug 02 #Redis
You might like
smarty高级特性之过滤器的使用方法
2015/12/25 PHP
PHP实现动态执行代码的方法
2016/03/25 PHP
PHP面向对象多态性实现方法简单示例
2017/09/27 PHP
PHP将英文数字转换为阿拉伯数字实例讲解
2019/01/28 PHP
XMLHTTP 乱码的解决方法(UTF8,GB2312 编码 解码)
2011/01/12 Javascript
jQuery 中使用JSON的实现代码
2011/12/01 Javascript
Javascript/Jquery——简单定时器的多种实现方法
2013/07/03 Javascript
javascript中RegExp保留小数点后几位数的方法分享
2013/08/13 Javascript
动态加载dtree.js树treeview(示例代码)
2013/12/17 Javascript
js关于精确计算和数值格式化以及直接引js文件
2014/01/28 Javascript
两种方法基于jQuery实现IE浏览器兼容placeholder效果
2014/10/14 Javascript
JavaScript 事件绑定及深入
2015/04/13 Javascript
JQuery鼠标移到小图显示大图效果的方法
2015/06/10 Javascript
javascript实现Email邮件显示与删除功能
2015/11/21 Javascript
第一次接触Bootstrap框架
2016/10/24 Javascript
Vue.js结合bootstrap实现分页控件
2017/03/10 Javascript
NodeJS实现图片上传代码(Express)
2017/06/30 NodeJs
vue+iview+less+echarts实战项目总结
2018/02/22 Javascript
vue 监听屏幕高度的实例
2018/09/05 Javascript
[01:53]3.19 DOTA2发布会 现场精彩Coser表演
2014/03/25 DOTA
简单的抓取淘宝图片的Python爬虫
2014/12/25 Python
python中字典dict常用操作方法实例总结
2015/04/04 Python
Python栈算法的实现与简单应用示例
2017/11/01 Python
Python3之简单搭建自带服务器的实例讲解
2018/06/04 Python
Python3 itchat实现微信定时发送群消息的实例代码
2019/07/12 Python
海蓝之谜(LA MER)澳大利亚官方商城:全球高端奢华护肤品牌
2017/10/27 全球购物
德国滑雪和户外用品网上商店:XSPO
2019/10/30 全球购物
英国Radley包德国官网:Radley London德国
2019/11/18 全球购物
文秘自荐信
2013/10/20 职场文书
授权委托书范本
2014/04/03 职场文书
结对共建工作方案
2014/06/02 职场文书
应届大专生自荐书
2014/06/16 职场文书
人事经理岗位职责范本
2014/08/04 职场文书
经典哲理警句:志不真则心不热,心不热则功不贤
2019/11/14 职场文书
Windows11里微软已经将驱动程序安装位置A盘删除
2021/11/21 数码科技
MySql统计函数COUNT的具体使用详解
2022/08/14 MySQL