Redis基础操作 (docker集成)

本文详细介绍了如何在Docker中安装Redis,包括常用命令、数据类型操作、事务处理、Jedis使用、Springboot集成及Redis缓存策略。内容涵盖Redis的基础操作如string、list、set等类型,还涉及事务、主从复制、哨兵模式,以及解决缓存穿透和雪崩问题的方法。
摘要由CSDN通过智能技术生成

docker安装redis

docker pull redis
docker run -itd --name redis -p 6379:6379 -v /home/admin/redis/redis.conf:/etc/redis/redis.conf -v /home/admin/redis/data:/data redis redis-server /etc/redis/redis.conf

docker安装完redis后内部是没有配置文件的,需要在创建之前指定

下面命令是让redis加载所给的配置文件

redis-server /etc/redis/redis.conf

redis.conf内容见附录

  • 进入redis容器,并进行相关操作
docker exec -it redis bash
  • 输入redis-cli,进入redis命令行
  • redis-cli中使用中文的值可能会有乱码

使用以下命令进入可以避免

redis-cli --raw

常用命令

  1. 切换数据库

数据库默认从0~15

  • select num
select 3
  1. 查看数据库数据大小
  • dbsize
dbsize
  1. 查看所有的键
  • keys *
keys *
  1. 清空当前数据库
  • flushdb
flushdb
  1. 清空全部数据库
  • flushall
flushall
  1. 查看某个键是否存在
  • exists key
exists name
  1. 设置某个键过期的时间
  • expire key second

设置键name失效的时间为5s

expire name 5
  1. 查看键剩余的时间
  • ttl key
ttl name
  1. 移动键到另一个数据库
  • move key dbindex

移动name到1号数据库

move name 1
  1. 查看数据类型
  • type key
type name
  1. 删除键
  • del key
del name

数据类型及相关操作

  • string
  • list
  • set
  • hash
  • zset(有序集合)

特殊数据类型

  • geospetial(地理位置)
  • hyperloglog(基数统计)
  • bitmap(位运算)

string类型操作

  1. 设置数据
  • set key value
set name zhangsan
  1. 查看数据
  • get key
get name
  1. 删除键
  • del key
del name
  1. 向字符串尾部追加数据
  • append key value
append name zhangsan
  1. 查看数据长度
  • strlen key
strlen name
  1. 数字字符串加1
  • incr key
incr age
  1. 数字字符串减1
  • decr key
decr age
  1. 数字字符串增加指定数量
  • incrby key num
incrby age 10
  1. 数字字符串减少指定数量
  • decrby key num
decrby age 5
  1. 截取数据
  • getrange key start end

截取键name中字符串0~3位置的字符

getrange name 0 3

截取全部字符串

 getrange name 0 -1
  1. 设置字符串中某位置开始的数据
  • setrange key index string

设置name数据中从1位置开始的数据为abc

setrange name 1 abc
  1. 设置键值同时指定过期时间
  • setex key second value
setex name 5 zhangsan
  1. 键值不存在再设置键值
  • setnx key value

如果name存在则不设置,否则设置键name的值为zhangsan

setnx name zhangsan
  1. 批量设置键值
  • mset key value …
mset k1 v1 k2 v2 k3 v3
  1. 批量获取值
  • mget key1 key2 …
mget k1 k2 k3
  1. 批量设置键值,有一个键已存在则失败
  • msetnx key value …

如果k1已存在,则整个操作失败(原子性)

msetnx k1 v1 k2 abc
  1. 巧设键
  • user:{id}:{filed}
mset user:1:name zhangsan user:1:age 4

获取值

mget user:1:name user:1:age
  1. 获取旧值设置新值
  • getset key value

返回旧值zhagnsan,设置新值lisi,旧值不存在则为null

getset name lisi

list类型操作

  1. 向左插入元素
  • lpush key value …

向左插入, 0位置为def

def, abc

lpush list abc
lpush list def

插入多个元素

lpush list a b c d e
  1. 向右插入元素
  • rpush key value

向右插入, 0位置为abc

abc, def

rpush list abc
rpush list def
  1. 查看元素
  • lrange key start stop
lrange list 0 -1
  1. 移除左边元素
  • lpop key
lpop list
  1. 移除右边元素
  • rpop key
rpop list
  1. 获取列表中某个值
  • lindex key index
lindex list 0
  1. 获取列表长度
  • llen key
llen list
  1. 移除列表中任意个数的值
  • lrem key count value

从左开始依次移除列表3个a

lrem list 3 a
  1. 在原列表中截取数据
  • ltrim key start stop

截取列表中0-5的数据,其余删除

ltrim list 0 5
  1. 移除列表最后一个元素,同时将该元素添加到新的列表中
  • rpoplpush key1 key2
rpoplpush list li
  1. 将指定下标的值替换
  • lset key index value

如果下标不存在则报错

lset list 0 abc
  1. 在某个值前后进行插入
  • linsert key before|after pivot value

从左往右,在第一个a前面插入b

linsert list before a b

从左往右,在第一个a后面插入b

linsert list after a b

set类型操作

set内的值无序,不能重复

  1. 添加元素
  • sadd key value …
sadd st a b c
  1. 查看元素
  • smembers key
smembers st
  1. 获取集合元素的个数
  • scard key
scard st
  1. 移除元素
  • srem key member …
srem st a b c
  1. 随机获取任意数量元素
  • srandmember key [count]
srandmember st
srandmember st 2
  1. 随机移除任意数量的元素
  • spop key [count]
spop st 3
  1. 将一个集合中的元素移动到另一个集合
  • smove source destination member

将集合st中的a元素移动到集合st2中

smove st st2 a
  1. 获取集合的差集
  • sdiff key1 key2 …

找出st1数据在st2、st3…中不存在的

sdiff st1 st2
  1. 获取集合的交集
  • sinter key1 key2 …

找出st1和st2…中共同拥有的元素

sinter st1 st2
  1. 获取集合的并集
  • sunion key1 key2 …
sunion st1 st2

hash类型操作

  1. 添加数据
  • hset key field value

在hash集合hs中添加一个键name,值为zhangsan

hset hs name zhangsan
  1. 查询数据
  • hget key field
hget hs name
  1. 批量添加数据
  • hmset key field value [field value …]
hmset hs name zhangsan age 4
  1. 批量查找数据
  • hmget key field [field …]
hmget hs name age
  1. 获取某个hash集合中所有的键值
  • hgetall key
hgetall hs
  1. 删除hash集合中的某个数据
  • hdel key field [field …]
hdel hs name
  1. 获取hash集合中的数据个数
  • hlen key
hlen hs
  1. 判断hash集合中的字段是否存在
  • hexists key field
hexists hs name
  1. 只获取所有的键
  • hkeys key
hkeys hs
  1. 只获取所有的值
  • hvals key
hvals hs
  1. 数字增加指定值
  • hincrby key field increment

num增加5

hincrby hs num 5

num减少5

hincrby hs num -5
  1. 存在则不添加,否则添加
  • hsetnx key field value
hsetnx hs name lisi

zset类型操作

  1. 添加数据
  • zadd key score member …
zadd zs 1 a 2 b 3 c 4 d
  1. 查看数据(按分数从小到大排序)
  • zrangebyscore key min max [WITHSCORES] [LIMIT offset count]

-inf, +inf 表示无穷小和无穷大

在集合zs中,寻找分数在[-∞, +∞]区间,按照从小到大排序

zrangebyscore zs -inf +inf

在集合zs中,寻找分数在[-∞, +∞]区间,按照从小到大排序, 附带分数

zrangebyscore zs -inf +inf withscores

min和max形成的区间是闭区间[min, max], 如果想要开区间(min, max)

zrangebyscore zs (1 (3 withscores
  1. 查看数据(按分数从大到小排序)
  • zrevrangebyscore key max min [WITHSCORES] [LIMIT offset count]
zrevrangebyscore zs +inf -inf withscores limit 0 2
  1. 查看某一范围内数据
  • zrange key start stop [WITHSCORES]
zrange zs 0 1
  1. 反转查看某一范围数据
  • zrevrange key start stop [WITHSCORES]
zrevrange zs 0 -1
  1. 删除数据
  • zrem key member [member …]
zrem zs a
  1. 获取集合元素的个数
  • zcard key
zcard zs
  1. 获取指定区间的元素个数
  • zcount key min max
zcount zs 2 3

geospetial类型操作

  1. 添加数据
  • geoadd key longitude latitude member [longitude latitude member …]
geoadd china:city 116.405285 39.904989 beijing
geoadd china:city 121.472644 31.231706 shanghai
geoadd china:city 106.504962 29.533155 chongqing
geoadd china:city 120.153576 30.287459 hangzhou
  1. 获取指定城市的经纬度值
  • geopos key member [member …]
geopos china:city beijing
  1. 获取两城市间的直线距离
  • geodist key member1 member2 [unit]

unit(单位):

  • m: 米

  • km:千米

  • mi: 英里

  • ft: 英尺

geodist china:city beijing shanghai
geodist china:city beijing shanghai km
  1. 获取附近的城市
  • georadius key longitude latitude radius m|km|ft|mi [WITHCOORD] [WITHDIST] [WITHHASH] [COUNT count] [ASC|DESC] [STORE key] [STOREDIST key]

查看经度110,纬度30附近800km内的城市

georadius china:city 110 30 800 km
  • withcoord:将位置元素的经度与纬度也一并返回
  • withdist:在返回位置元素的同时,将距离也一并返回。距离的单位和用户给定的范围单位保持一致
  • withhash:以52位的符号整数形式,返回位置元素经过geohash编码的有序集合分值。用于底层应用或调试,实际作用不大。
  • sort取值范围
    • asc:根据中心位置,按照从近到远的方式返回位置元素
    • desc:根据中心位置,按照从远到近的方式返回位置元素
  • store key:将返回结果而的地理位置信息保存到指定键
  • storedist key:将返回结果距离中心节点的距离保存到指定键

查看经度110,纬度30附近800km内的城市, 并附带经纬度、距离,按城市距离进行从近到远排序,返回前两个

georadius china:city 110 30 8000 km withcoord withdist count 2 asc
  1. 获取城市的hash表示
  • geohash key member [member …]

返回11个字符的字符串,将二维的经纬度转化为字符串,字符串越接近,距离越近

geohash china:city beijing shanghai
  1. geospetial底层基于zset,可以通过zset的相关命令操作geospetial
zrange china:city 0 -1
zrem china:city beijing

hyperloglog类型操作

  1. 添加数据
  • pfadd key element [element …]
pfadd pf a b c d e
  1. 查看元素个数
  • pfcount key [key …]
pfcount pf
  1. 合并集合
  • pfmerge destkey sourcekey [sourcekey …]

将pf1和pf2中的数据合并到pf3中,去除重复的

pfmerge pf3 pf1 pf2

bitmap类型操作

  1. 添加数据
  • setbit key offset value
setbit bm 1 0
setbit bm 2 1
setbit bm 3 1
  1. 获取数据
  • getbit key offset
getbit bm 3
  1. 统计1的个数
  • bitcount key [start end]
bitcount bm

事务

执行事务

redis的事务:

  • 开始事务(multi)
  • 命令入队
  • 执行事务(exec) / 放弃事务(discard)
multi
set k1 v1
set k2 v2
set k3 v3
get k2
exec

异常

  1. 编译型异常(代码、命令有问题): 事务中所有的命令都不会被执行
multi
set k1
set k2 v2
exec
  1. 运行时异常(语法问题): 命令可以执行,错误命令抛出异常
multi
incr k1
set k2 1
incr k2
exec

监控

  1. 悲观锁

认为任何时候都会出问题,无论做什么都会加锁

  1. 乐观锁

认为任何时候都不会出问题,所以不会上锁。在更新数据的时候判断是否有人修改过这个数据

使用乐观锁测试多线程修改值

  • 终端1
set money 100
set out 0
watch money
multi
decrby money 20
incrby out 20
  • 终端2
multi
set money 50
exec
  • 终端1
exec

此时终端1的操作会失败

watch可以当做redis的乐观锁,当使用该命令时,redis会监测数据变化情况,如果在此期间进行数据的更新,则事务操作失败。

unwatch可以进行解锁

jedis使用

环境配置

pom.xml

<dependency>
    <groupId>redis.clients</groupId>
    <artifactId>jedis</artifactId>
</dependency>
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>fastjson</artifactId>
    <version>1.2.71</version>
</dependency>

基本使用

jedis的使用和命令一致

Jedis jedis = new Jedis("127.0.0.1", 6379);
jedis.flushDB();
jedis.set("username", "zhangsan");
System.out.println(jedis.get("username"));
jedis.lpush("li", "1");
jedis.lpush("li", "2");
System.out.println(jedis.lrange("li", 0, -1));

事务操作

Jedis jedis = new Jedis("127.0.0.1", 6379);
JSONObject jsonObject = new JSONObject();
jsonObject.put("username", "zhangsan");

jedis.watch("user");
// 开启事务
Transaction transaction = jedis.multi();

try {
   
    transaction.set("user", jsonObject.toJSONString());
    // 执行事务
    transaction.exec();
} catch (Exception e) {
   
    // 放弃事务
    transaction.discard();
    e.printStackTrace();
} finally {
   
    jedis.close();
}
System.out.println(jedis.get("user"));

Springboot集成redis

环境配置

pom.xml

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

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-devtools</artifactId>
        <scope>runtime</scope>
        <optional>true</optional>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-configuration-processor</artifactId>
        <optional>true</optional>
    </dependency>
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <optional>true</optional>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
        <exclusions>
            <exclusion>
                <groupId>org.junit.vintage</groupId>
                <artifactId>junit-vintage-engine</artifactId>
            </exclusion>
        </exclusions>
    </dependency>
</dependencies>

application.properties

spring.redis.host=localhost
spring.redis.port=6379

基本操作

数据库操作

// 获取redis的连接对象
RedisConnection connection = redisTemplate.getConnectionFactory().getConnection();
connection.flushAll();
connection.flushDb();

不同数据类型操作

// 不同数据类型操作
redisTemplate.opsForValue();
redisTemplate.opsForList();
redisTemplate.opsForSet();
redisTemplate.opsForHash();
redisTemplate.opsForZSet();
redisTemplate.opsForGeo();
redisTemplate.opsForHyperLogLog();

自定义redisTemplate

@Configuration
public class RedisConfig {
   

    @Bean
    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
   
        RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
        redisTemplate.setConnectionFactory(redisConnectionFactory);
        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);
        jackson2JsonRedisSerializer.setObjectMapper(objectMapper);

        // String的序列化
        StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
        // key采用String的序列化方式
        redisTemplate.setKeySerializer(stringRedisSerializer);
        // hash采用String的序列化方式
        redisTemplate.setHashKeySerializer(RedisSerializer.string());
        // value序列化采用jackson方式
        redisTemplate.setValueSerializer(jackson2JsonRedisSerializer);
        // hash的value序列化采用jackson方式
        redisTemplate.setHashValueSerializer(jackson2JsonRedisSerializer);
        redisTemplate.afterPropertiesSet();
        return redisTemplate;
    }
}

RedisUtil工具类封装

@Component
public class
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值