文章目录

  • 前导
    • 全局命令
      • 查看所有键 keys *
      • 键总数dbsize
      • 检查键是否存在 exists key
      • 删除键del key
      • 键过期expire key seconds
      • 键的数据结构类型type key
    • 数据结构和内部编码
    • 单线程架构
  • string概述
  • 基本命令
  • string的内部编码
  • 客户端操作
    • Spring中操作redis的字符串
      • spring-redis-string.xml
      • SpringRedisStringsDemo
  • Redis中对整数和浮点型数字的支持
    • 客户端操作
    • Spring中操作redis的字符串的加减运算
  • 注意
  • 常见使用场景
    • 缓存
    • 计数器
    • 限流
    • session共享
    • 分布式锁
  • 代码

前导

在了解具体的数据结构类型之前,我们有必要了解下Redis提供的操作key的全局命令、 数据结构和内部编码、 单线程命令处理机制,都有助于加深对Redis的理解。

全局命令

Redis 是一个Key-Value内存数据库,不管是何种数据结构,对于键来说有一些通用的命令。简单句几个例子

查看所有键 keys *

keys * 命令会将所有的键输出

127.0.0.1:6379> set  key1 artisan
OK
127.0.0.1:6379> set key2 artisan2
OK
127.0.0.1:6379> set key3 artisan3
OK
127.0.0.1:6379> keys *
1) "key3"
2) "key2"
3) "key1"
127.0.0.1:6379> 

keys命令会遍历所有键, 所以它的时间复杂度是O(n) , 当Redis保存了大量键时, 线上环境 禁止使用


键总数dbsize

dbsize命令会返回当前数据库中键的总数

127.0.0.1:6379> rpush artisanlist a d d d x we  sdsd  dsd sddfdg  dsfdf  sdfsdfsdf  sdfsfdf   ---- 返回增加的list的个数
(integer) 12
127.0.0.1:6379> dbsize   --加上刚才设置的3个,一共4个key
(integer) 4
127.0.0.1:6379> keys *
1) "artisanlist"
2) "key3"
3) "key2"
4) "key1"
127.0.0.1:6379> 

dbsize命令在计算键总数时不会遍历所有键, 而是直接获取Redis内置的键总数变量, 所以dbsize命令的时间复杂度是O(1)


检查键是否存在 exists key

127.0.0.1:6379> exists  artisanlist
(integer) 1
127.0.0.1:6379> exists sdsdsd
(integer) 0
127.0.0.1:6379> 

如果键存在则返回1, 不存在则返回0


删除键del key

127.0.0.1:6379> del key1
(integer) 1
127.0.0.1:6379> del xdsdse
(integer) 0
127.0.0.1:6379> 

del是一个通用命令, 无论值是什么数据结构类型, del命令都可以将其删除

27.0.0.1:6379> exists artisanlist
(integer) 1
127.0.0.1:6379> del artisanlist
(integer) 1
127.0.0.1:6379> exists artisanlist
(integer) 0
127.0.0.1:6379> 

返回结果为成功删除键的个数, 假设删除一个不存在的键, 返回0,如上。

同时del命令可以支持删除多个键

127.0.0.1:6379> set x 123
OK
127.0.0.1:6379> set y 456
OK
127.0.0.1:6379> set z 789
OK
127.0.0.1:6379> del x y z
(integer) 3
127.0.0.1:6379> 

键过期expire key seconds

Redis支持对键添加过期时间, 当超过过期时间后, 会自动删除键

ttl命令会返回键的剩余过期时间 ,它有三种返回值

  • 大于等于0的整数: 键剩余的过期时间。
  • -1: 键没设置过期时间。
  • -2: 键不存在
127.0.0.1:6379> set name artisan
OK
127.0.0.1:6379> expire name 20
(integer) 1
127.0.0.1:6379> ttl name
(integer) 16
.....
127.0.0.1:6379> ttl name
(integer) 1
127.0.0.1:6379> ttl name   -- -2说明不存在
(integer) -2
127.0.0.1:6379> get name  --- get为空
(nil)
127.0.0.1:6379> 

上面的 set name artisan expire name 20 两句 可以简化成 set name artisan EX 20

语法如下

set key value [expiration EX seconds|PX milliseconds] [NX|XX
127.0.0.1:6379> set name artisan EX 20
OK
127.0.0.1:6379> ttl name
(integer) 16
127.0.0.1:6379> get name
"artisan"
.......
127.0.0.1:6379> ttl name
(integer) 1
127.0.0.1:6379> ttl name
(integer) -2
127.0.0.1:6379> 

键的数据结构类型type key

键name 是字符串类型, 返回结果为string,
键artisanlist是列表类型, 返回结果为list,
键user是列表hash, 返回结果为hash

127.0.0.1:6379> set name artisan
OK
127.0.0.1:6379> rpush artisanlist asds sddfd sdfdsf dfdfsfd sdfsdfsd f
(integer) 6
127.0.0.1:6379> hset user name artisan2 age 20 country china sex male
(integer) 4
127.0.0.1:6379> type name
string
127.0.0.1:6379> type artisanlist
list
127.0.0.1:6379> type user
hash
127.0.0.1:6379> 

数据结构和内部编码

type命令实际返回的就是当前键的数据结构类型: string(字符串) 、 hash(哈希) 、 list(列表) 、 set(集合) 、 zset(有序集合) , 其实这些只是Redis对外的数据结构。 事实上,Redis内部每种数据结构都有自己底层的内部编码实现, 而且是多种实现,Redis会在合适的场景选择合适的内部编码。

可以通过object encoding命令查询内部编码

127.0.0.1:6379> set name artisan
OK
127.0.0.1:6379> LPUSH artisanlist c b a
(integer) 9
127.0.0.1:6379> hset user name artisan age 20 sex male
(integer) 0
127.0.0.1:6379> sadd myset a b c
(integer) 3
127.0.0.1:6379> zadd myzset 90 artisan
(integer) 1
127.0.0.1:6379> object encoding name
"embstr"
127.0.0.1:6379> object encoding user
"ziplist"
127.0.0.1:6379> object encoding myset
"hashtable"
127.0.0.1:6379> object encoding myzset
"ziplist"
127.0.0.1:6379>

单线程架构

Redis使用了单线程架构I/O多路复用模型来实现高性能的内存数据库服务。

为什么Redis使用单线程模型会达到每秒万级别的处理能力呢?

  1. 纯内存访问, Redis将所有数据放在内存中, 内存的响应时长大约为100纳秒, 这是Redis达到每秒万级别访问的重要基础
  2. 非阻塞I/O, Redis使用epoll作为I/O多路复用技术的实现, 再加上Redis自身的事件处理模型将epoll中的连接、 读写、 关闭都转换为事件, 不在网络I/O上浪费过多的时间
  3. 单线程避免了线程切换和竞态产生的消耗

string概述

字符串是 Redis 最基本的数据结构 ,它将以一个键和一个值存储于 Redis 内部,很像Java 的 Map 结构 ,让 Redis 通过键去找到值。

Redis 会通过 key 去找到对应的字符串 ,比如通过 keyl 找到 valuel。假设产品的编号为 0001 , 只要设置 key 为 product_0001 , 就可以通过 product_0001去保存该产品到 Redis 中,也可以通过 product_0001 从 redis 中找到产品信息。

字符串类型的值实际可以 是字符串(简单的字符串、 复杂的字符串(例如JSON、 XML) ) 、 数字 (整数、 浮点数) , 甚至是二进制(图片、 音频、 视频) , 但是值最大不能 超过512MB。


基本命令

官网 : https://redis.io/commands#string

中文网站: http://www.redis.cn/commands.html#string

这里仅仅列出常用的一些,其他详见上述官网

命令 说明 备注
set key value 设置键值对 最常用的写入命令
get key 通过键获取值 最常用的读取命
del key 通过 key ,删除键值对 删除命令,返刨删除数,注意,它是一个通用的命令,换句话说在其他数据纺构中,也可以使用它
strlen key 求 key 指向字符串的氏度 返回长度
getset key value 修改原来 key 的对应值,并将旧值返回 如果原来值为空,则返回为空,并设置新值
getrange key start end 获取子串 记字符串的长度为 len,把字符串看作一个数组,而Redis 是以 0 开始计数的,所以 s tart 和l end 的取值范为 0 到 len-1
append key value 将新的字符串value加入到原来 key指向的字符串末 返回 key 指向新字符净的长度

set key value [ex seconds] [px milliseconds] [nx|xx]
  • ex seconds: 为键设置秒级过期时间。

  • px milliseconds: 为键设置毫秒级过期时间。

  • nx: 键必须不存在, 才可以设置成功, 用于添加。

  • xx: 与nx相反, 键必须存在, 才可以设置成功, 用于更新

除了set选项, Redis还提供了setex和setnx两个命令

设置过期时间

setex key seconds value

setnx当前键不存在,允许设置

setnx key value
127.0.0.1:6379> set  key1 value1
OK
127.0.0.1:6379> setnx key1 value2  -- 因为存在,所以设置key1 失败,返回0
(integer) 0
127.0.0.1:6379> setex key1 100 vlaue3 -- 设置过期时间 100秒
OK
127.0.0.1:6379> get key1
"vlaue3"
127.0.0.1:6379> ttl key1
(integer) 93
127.0.0.1:6379> ttl key1
(integer) 88

setnx和setxx在实际使用中有什么应用场景吗? 以setnx命令为例子, 由于Redis的单线程命令处理机制, 如果有多个客户端同时执行setnx key value,根据setnx的特性只有一个客户端能设置成功, setnx可以作为分布式锁的一种实现方案。


批量设置值

mset key value [key value ...]
127.0.0.1:6379> mset key1 a key2 b key3 c key4 d key5 5
OK

批量获取值

 mget key [key ...]
127.0.0.1:6379> mget key1 key2 key3 key4 key5
1) "a"
2) "b"
3) "c"
4) "d"
5) "5"

如果有些键不存在, 那么它的值为nil(空) , 结果是按照传入键的顺序返回:

127.0.0.1:6379> mget key1 key2 xxx key3
1) "a"
2) "b"
3) (nil)
4) "c"
127.0.0.1:6379> 

批量操作命令可以有效提高效率,假如没有mget这样的命令, 要执行n次get命令如下所示

n次get时间 = n次网络时间 + n次命令时间

使用mget命令后, 要执行n次get命令操作如下

n次get时间 = 1次网络时间 + n次命令时间

Redis可以支撑每秒数万的读写操作, 但是这指的是Redis服务端的处理能力, 对于客户端来说, 一次命令除了命令时间还是有网络时间, 假设网络时间为1毫秒, 命令时间为0.1毫秒(按照每秒处理1万条命令算) , 那么执行1000次get命令和1次mget命令如下

因为Redis的处理能力已经足够高,所以 网络可能会成为性能的瓶颈。

使用批量操作, 有助于提高业务处理效率, 但是要注意的是每次批量操作所发送的命令数不是无节制的, 如果数量过多可能造成Redis阻塞或者网络拥塞。


string的内部编码

字符串类型的3种内部编码

1. int: 8个字节的长整型

2. embstr: 小于等于39个字节的字符串

3. raw: 大于39个字节的字符串

Redis会根据当前值的类型和长度决定使用哪种内部编码实现。

127.0.0.1:6379> set k1 1234
OK
127.0.0.1:6379> object encoding k1
"int"
127.0.0.1:6379> set k2 "my name is artisan"
OK
127.0.0.1:6379> object encoding k2
"embstr"
127.0.0.1:6379> STRLEN k2
(integer) 18
127.0.0.1:6379> set k3 "sdfdfsdfsdfdf sfds dfsdfs dsf  sfsdfs fd fsf fs sf sfds fdfs fsdf sfs fsdf sdfs f ssfd fsd fdf sfsdf f"
OK
127.0.0.1:6379> STRLEN k3
(integer) 102
127.0.0.1:6379> object encoding k3
"raw"
127.0.0.1:6379> 

客户端操作

我这里的redis server设置了密码,密码为artisan ,所以有

 auth artisan

[redis@artisan bin]$ pwd
/home/redis/redis/redis-4.0.11/bin
[redis@artisan bin]$ ./redis-cli
127.0.0.1:6379> auth artisan
OK
127.0.0.1:6379> set key1 value1
OK
127.0.0.1:6379> set key2 value2
OK
127.0.0.1:6379> get key1
"value1"
127.0.0.1:6379> del key1
(integer) 1
127.0.0.1:6379> strlen key2
(integer) 6
127.0.0.1:6379> getset key2 new_value2
"value2"
127.0.0.1:6379> get key2
"new_value2"
127.0.0.1:6379> getrange key2 0 3
"new_"
127.0.0.1:6379> append key2 _app
(integer) 14
127.0.0.1:6379> get key2
"new_value2_app"
127.0.0.1:6379>

Spring中操作redis的字符串

spring-redis-string.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"xmlns:p="http://www.springframework.org/schema/p"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"><context:property-placeholder location="classpath:redis/redis.properties" /><!--2,注意新版本2.3以后,JedisPoolConfig的property name,不是maxActive而是maxTotal,而且没有maxWait属性,建议看一下Jedis源码或百度。 --><!-- redis连接池配置 --><bean id="jedisPoolConfig" class="redis.clients.jedis.JedisPoolConfig"><!--最大空闲数 --><property name="maxIdle" value="${redis.maxIdle}" /><!--连接池的最大数据库连接数 --><property name="maxTotal" value="${redis.maxTotal}" /><!--最大建立连接等待时间 --><property name="maxWaitMillis" value="${redis.maxWaitMillis}" /><!--逐出连接的最小空闲时间 默认1800000毫秒(30分钟) --><property name="minEvictableIdleTimeMillis" value="${redis.minEvictableIdleTimeMillis}" /><!--每次逐出检查时 逐出的最大数目 如果为负数就是 : 1/abs(n), 默认3 --><property name="numTestsPerEvictionRun" value="${redis.numTestsPerEvictionRun}" /><!--逐出扫描的时间间隔(毫秒) 如果为负数,则不运行逐出线程, 默认-1 --><property name="timeBetweenEvictionRunsMillis" value="${redis.timeBetweenEvictionRunsMillis}" /><property name="testOnBorrow" value="true"></property><property name="testOnReturn" value="true"></property><property name="testWhileIdle" value="true"></property></bean><!--redis连接工厂 --><bean id="jedisConnectionFactory"class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory"destroy-method="destroy"><property name="poolConfig" ref="jedisPoolConfig"></property><!--IP地址 --><property name="hostName" value="${redis.host.ip}"></property><!--端口号 --><property name="port" value="${redis.port}"></property><!--如果Redis设置有密码 --><property name="password" value="${redis.password}" /> <!--客户端超时时间单位是毫秒 --><property name="timeout" value="${redis.timeout}"></property><property name="usePool" value="true" /><!--<property name="database" value="0" /> --></bean><!-- 键值序列化器设置为String 类型 --><bean id="stringRedisSerializer" class="org.springframework.data.redis.serializer.StringRedisSerializer"/><!-- redis template definition --><bean id="redisTemplate" class="org.springframework.data.redis.core.RedisTemplate"p:connection-factory-ref="jedisConnectionFactory"p:keySerializer-ref="stringRedisSerializer"p:valueSerializer-ref="stringRedisSerializer"></bean></beans>

SpringRedisStringsDemo

package com.artisan.redis.baseStructure.strings;import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.data.redis.core.RedisTemplate;public class SpringRedisStringsDemo {public static void main(String[] args) {ApplicationContext ctx = new ClassPathXmlApplicationContext("classpath:spring/spring-redis-string.xml");// 在 Spring 中,// redisTemplate.opsForValue()所返回的对象可以操作简单的键值对,可以是字符串,也可以是对象,具体依据你所配置的序列化方案// 这里在spring-redis-string.xml中key和value都是指定的 stringRedisSerializerRedisTemplate<String,String> redisTemplate = (RedisTemplate<String, String>) ctx.getBean("redisTemplate");// 设置值//127.0.0.1:6379> set key1 value1//OK//127.0.0.1:6379> set key2 value2//OKredisTemplate.opsForValue().set("key1", "value1");redisTemplate.opsForValue().set("key2", "value2");// 通过 key 获取值//127.0.0.1:6379> get key1//"value1"String key1 = redisTemplate.opsForValue().get("key1");System.out.println("key1:" + key1);// 通过 key 删除值//127.0.0.1:6379> del key1//(integer) 1Boolean success = redisTemplate.delete("key1");System.out.println("删除key1是否成功:" + success);// 求长度//127.0.0.1:6379> strlen key2//(integer) 6Long size = redisTemplate.opsForValue().size("key2");System.out.println("key2长度:" + size);// 设值新值并返回旧值//127.0.0.1:6379> getset key2 new_value2//"value2"String oldValue = redisTemplate.opsForValue().getAndSet("key2", "new_value2");System.out.println("key2旧值:" + oldValue);// 127.0.0.1:6379> get key2// "new_value2"String newValue = redisTemplate.opsForValue().get("key2");System.out.println("key2新值:" + newValue);// 获取子串// 127.0.0.1:6379> getrange key2 0 3// "new_"String subString = redisTemplate.opsForValue().get("key2", 0, 3);System.out.println("subString:" + subString);// 将新的字符串value加入到原来 key指向的字符串末// 127.0.0.1:6379> append key2 _app// (integer) 14Integer value = redisTemplate.opsForValue().append("key2", "_app");System.out.println("value:" + value);// 127.0.0.1:6379> get key2// "new_value2_app"String newValue2 = redisTemplate.opsForValue().get("key2");System.out.println("key2:" + newValue2);}
}

首先在客户端中flushdb,确保数据干净。

输出

redis中的数据


Redis中对整数和浮点型数字的支持

上面介绍了字符串最常用的命令 , 但是 Redis 除了这些之外还提供了对整数和浮点型数字的功能,如果字符串是数字(整数或者浮点数〉,那么 Redis 还能支持简单的运算。但是它的运算能力比较弱 , 目前版本只能支持简单的加减法运算。

命令 说明 备注
incr key 在原字段上加 1 只能对整数操作
incrby key increment 在原字段上加上整数( increment ) 只能对整数操作
decr key 在原字段上减 1 只能对整数操作
decrby key decrement 在原字段上减去整数( decrement ) 只能对整数操作
incrbyfloat keyincrement 在原字段上加上浮点数( increment) 可以操作浮点数或者整

客户端操作

[redis@artisan bin]$ ./redis-cli
127.0.0.1:6379> auth artisan
OK
127.0.0.1:6379> flushdb
OK
127.0.0.1:6379> set number 8
OK
127.0.0.1:6379> GET number
"8"
127.0.0.1:6379> INCR number
(integer) 9
127.0.0.1:6379> INCRBY number 5
(integer) 14
127.0.0.1:6379> DECR number
(integer) 13
127.0.0.1:6379> DECRBY number 10
(integer) 3
127.0.0.1:6379> INCRBYFLOAT number 8.88
"11.88"
127.0.0.1:6379> get number
"11.88"
127.0.0.1:6379> 

如果开始把val 设置为浮点数,那么 incr、 deer、 incrby 、 deerby 的命令都会失败。 Redis 并不支持减法 、 乘法、除法操作,功能十分有限,需要注意。


Spring中操作redis的字符串的加减运算


package com.artisan.redis.baseStructure.strings;import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.data.redis.core.RedisTemplate;public class SpringRedisStringAdd_Subtraction {public static void main(String[] args) {ApplicationContext ctx = new ClassPathXmlApplicationContext("classpath:spring/spring-redis-string.xml");RedisTemplate redisTemplate = (RedisTemplate) ctx.getBean("redisTemplate");// 127.0.0.1:6379> set number 8// OKredisTemplate.opsForValue().set("number", String.valueOf(8));// 127.0.0.1:6379> GET number// "8"System.out.println(redisTemplate.opsForValue().get("number"));// 127.0.0.1:6379> INCR number// (integer) 9System.out.println(redisTemplate.opsForValue().increment("number", 1));// 127.0.0.1:6379> INCRBY number 5// (integer) 14System.out.println(redisTemplate.opsForValue().increment("number", 5));// 127.0.0.1:6379> DECR number// (integer) 13Long number = redisTemplate.getConnectionFactory().getConnection().decr(redisTemplate.getKeySerializer().serialize("number"));System.out.println(number);// 127.0.0.1:6379> DECRBY number 10// (integer) 3Long number2 = redisTemplate.getConnectionFactory().getConnection().decrBy(redisTemplate.getKeySerializer().serialize("number"), 10);System.out.println(number2);// 127.0.0.1:6379> INCRBYFLOAT number 8.88// "11.88"System.out.println(redisTemplate.opsForValue().increment("number", 8.88));// 127.0.0.1:6379> get number// "11.88"System.out.println(redisTemplate.opsForValue().get("number"));}}

在配置文件中使用的是字符串序列化器,所以 Redis 保存的还是字符串 ,如果采用其他的序列化器,比如 JDK 序列化器,那么 Redis 保存的将不会是数字而是产生异常。

Spring 己经优化了代码,所increment 方法可 以支持long和double的加法,如下

对于减法, RedisTemplate 并没有进行支持。 所以用下面的代码去代替它

redisTemplate . getConnectionFactory() .getConnection() . decrBy(redisTemplate.getKeySerializer() . serialize ("number") , 10) ;

通过获得连接工厂再获得连接从而得到底层的 Redis 连接对象。为了和 RedisTemplate的配置保持一致 ,所以先获取了其 keySerializer 属性 ,对键进行了序列化,如果获取结果也可以进行同样的转换。

当然 getConnection()只是获取一个 spring data redis 项目中封装的底层对象 RedisConnection , 甚至可以获取原始的链接对象Jedis 对象。

Jedis jedis =(Jedis)redisTemplate.getConnectionFactory() .getConnection() .getNativeConnection() ;

关于减法的方法,原有值都必须是整数,否则就会引发异常.

// 如果进行减法运算原有值都必须是整数,否则就会引发异常,比如下面的,编译通过,但运行会抛出异常
redisTemplate.opsForValue().set("number", "1.1");
redisTemplate.getConnectionFactory().getConnection().decr(redisTemplate.getKeySerializer().serialize("number"));
Exception in thread "main" org.springframework.dao.InvalidDataAccessApiUsageException: ERR value is not an integer or out of range; nested exception is redis.clients.jedis.exceptions.JedisDataException: ERR value is not an integer or out of rangeat org.springframework.data.redis.connection.jedis.JedisExceptionConverter.convert(JedisExceptionConverter.java:64)at org.springframework.data.redis.connection.jedis.JedisExceptionConverter.convert(JedisExceptionConverter.java:41)at org.springframework.data.redis.PassThroughExceptionTranslationStrategy.translate(PassThroughExceptionTranslationStrategy.java:44)at org.springframework.data.redis.FallbackExceptionTranslationStrategy.translate(FallbackExceptionTranslationStrategy.java:42)at org.springframework.data.redis.connection.jedis.JedisConnection.convertJedisAccessException(JedisConnection.java:181)at org.springframework.data.redis.connection.jedis.JedisStringCommands.convertJedisAccessException(JedisStringCommands.java:757)at org.springframework.data.redis.connection.jedis.JedisStringCommands.decr(JedisStringCommands.java:469)at org.springframework.data.redis.connection.DefaultedRedisConnection.decr(DefaultedRedisConnection.java:301)at com.artisan.redis.baseStructure.strings.SpringRedisStringAdd_Subtraction.main(SpringRedisStringAdd_Subtraction.java:49)
Caused by: redis.clients.jedis.exceptions.JedisDataException: ERR value is not an integer or out of rangeat redis.clients.jedis.Protocol.processError(Protocol.java:127)at redis.clients.jedis.Protocol.process(Protocol.java:161)at redis.clients.jedis.Protocol.read(Protocol.java:215)at redis.clients.jedis.Connection.readProtocolWithCheckingBroken(Connection.java:340)at redis.clients.jedis.Connection.getIntegerReply(Connection.java:265)at redis.clients.jedis.BinaryJedis.decr(BinaryJedis.java:708)at org.springframework.data.redis.connection.jedis.JedisStringCommands.decr(JedisStringCommands.java:467)... 2 more

注意

使用 Spring 提供的 RedisTemplate 去展示多个命令可以学习到如何使用 RedisTemplate 操作 Redis 。 实际工作中并不是那么用的,因为每一 个操作会尝试从连接池里获取 一 个新的 Redis 连接,多个命令应该使用SessionCallback 接口进行操作 。


常见使用场景

仅列举常见场景,不展开描述

缓存

Redis作为缓存层, 绝大部分请求的数据都是从Redis中获取。由于Redis具有支撑高并发的特性, 所以缓存通常能起到加速读写和降低后端压力的作用。

计数器

使用Redis作为计数的基础工具, 它可以实现快速计数、查询缓存的功能, 同时数据可以异步落地到其他数据源。


限流

举个例子,对某个接口在1分钟内限制调用10次


session共享

使用Redis将用户的Session进行集中管理,在这种模式下只要保证Redis是高可用和扩展性的, 每次用户更新或者查询登录信息都直接从Redis中集中获取


分布式锁

http://www.importnew.com/27477.html


代码

代码托管到了 https://github.com/yangshangwei/redis_learn

Redis-03Redis数据结构--全局命令及字符串string相关推荐

  1. 深入剖析Redis系列(四) - Redis数据结构与全局命令概述

    前言 Redis 提供了 5 种数据结构.理解每种数据结构的特点,对于 Redis 的 开发运维 非常重要,同时掌握 Redis 的 单线程命令处理 机制,会使 数据结构 和 命令 的选择事半功倍. ...

  2. Redis核心数据结构ZSET、GeoHash 、 Stream--排行榜、消息Pull推送、附近搜索、布隆过滤器 、IM聊天室

    ZSET.Geo . Stream redis zset数据结构 常用命令 排行榜 步骤一.初始化1个月的历史数据 步骤二:定时刷新数据 步骤3:排行榜查询接口 GeoHash 命令 附近酒店搜索实现 ...

  3. php两个数组之间去重,php数组去重、魔术方法、redis常用数据结构及应用场景

    一.用函数对数组进行去重的方法 1. arrau_unique函数的作用 移除数组中重复的值. 将值作为字符串进行排序,然后保留 每个值第一次 出现的健名,健名保留不变. 第二个参数可以选择排序方式: ...

  4. Redis系列:Redis的数据结构

    Redis 的基本数据类型包括:二进制安全字符串 String.Hashes(哈希).Lists 列表.Sets 集合 和 Sorted sets 有序集合: Redis 的特殊数据类型还包括:geo ...

  5. redis 基础数据结构实现

    参考文献 redis数据结构分析 Skip List(跳跃表)原理详解 redis 源码分析之内存布局 Redis 基础数据结构与对象 Redis设计与实现-第7章-压缩列表 在redis中构建了自己 ...

  6. Redis实战(2)-数据结构之字符串String实战之存储对象

    概述:本系列博文所涉及的相关内容来源于debug亲自录制的实战课程:缓存中间件Redis技术入门与应用场景实战(SpringBoot2.x + 抢红包系统设计与实战),感兴趣的小伙伴可以点击自行前往学 ...

  7. redis 五大数据结构__常用命令

    linux 下下载redis数据库 apt install redis 如果提示权限不够的话, 直接提权: sudo apt install redis-server linux启用.停止服务 ser ...

  8. Redis 常用数据结构及其控制命令整合

    Redis 键值支持5种基本结构,分别是字符串,列表,哈希,集合,有序集合.每一种数据结构都有对应的取值和设值命令,辅助命令,除此之外,还有一些全局命令,用来管理Redis存储的所有键. 全局命令 针 ...

  9. redis的数据结构||1) 字符串类型2) 哈希类型3) 列表类型4) 集合类型 5) 有序集合类型详解

    2. 下载安装     1. 官网:https://redis.io     2. 中文网:http://www.redis.net.cn/     3. 解压直接可以使用:         * re ...

  10. Redis常用命令之操作String类型

    场景 Centos中Redis的下载编译与安装(超详细): https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/details/103967334 Re ...

最新文章

  1. 使用ajax和history.pushState无刷新改变页面URL
  2. 【PC工具】图片批量添加水印工具,绿色免安装工具软件
  3. 有窗体和无窗体覆盖的问题
  4. 吴恩达 coursera AI 专项四第二课总结+作业答案
  5. 一站式服务!图片+代码-构建移动版旅游网站页面
  6. 适合python开发的linux版本,Python Linux下安装多个版本
  7. ABP入门系列(10)——扩展AbpSession
  8. Python应该怎么去练习和使用
  9. potplayer最全使用教程,【无边框透明美化教程】+【全球IPTV电视直播教程】+【不用下载观看影视剧教程】!
  10. 顺序表的基本操作(超详细)
  11. 如何有效破解PDF文件的密码?
  12. python中返回上一步操作的快捷键_在计算机中返回上一步的快捷键
  13. 蓝屏总结(二)——系统蓝屏及转储方法
  14. A*算法解决8数码问题python实现
  15. ssm+java农村快递代取平台52wxh(程序+lw+源码+远程部署)
  16. 业余爱好者,学习JAVA在实际中有什么用途?
  17. 计算机本科论文胶装封面颜色,毕业论文装订、存档详解
  18. 我的世界优化服务器ip,我的世界1.9.4服务器ip
  19. 为什么要基于模型设计?
  20. 【C语言】分支语句和循环语句还能这么用?一篇带你重新认识它(两万字超细详解)

热门文章

  1. 安信可ESP8266开发环境搭建
  2. 【语音信号处理课程设计】基于MATLAB的隐马尔可夫和矢量量化的语音识别研究
  3. 善领dsa2020最新车机ce版_理想汽车回应碰撞事故 硬件升级计划将推出OTA 2.0版
  4. android接口和type c对比,USB Type-C究竟比3.5mm音频接口好在哪里?
  5. jmeter录制 过滤_Jmeter(二)-使用代理录制脚本
  6. matlab矩阵逆时针旋转90度_matlab矩阵旋转任意角度的函数 imrotate
  7. 使用hping3进行DoS攻击
  8. python + selenium 之网银爬虫
  9. 激光雷达SLAM三维建图、点云算法 点云处理 自己写的算法 没用任何现成的库文件
  10. 用VBA下载google图片