欢迎光临
我们一直在努力

Redis 笔记

Redis 简介

redis 是以 key-value 形式存储,和传统的关系型数据库不一样,不一定遵循传统数据库的一些基本要求。redis 是非关系型的,分布式的,开源的,水平可拓展的

优点:

  • 对数据高并发读写(直接是内存中进行读写的)
  • 对海量数据的高效率存储和访问
  • 对数据的可拓展性和高可用性
  • 单线程操作,每个操作都是原子操作,没有并发相关问题

缺点:

  • 无法做太复杂的关系数据库模型

关系型数据库和非关系型数据库的区别

比较项关系型数据库非关系型数据库
数据模型 表格结构,多个表之间有关联 灵活模型(文档、键值、图等)
查询能力 SQL标准,强一致性 多样化查询语法
事务支持 强事务 弱事务或有限支持
适用场景 数据结构稳定 高扩展需求、灵活模式或特殊数据结构

数据类型及常用命令

String 字符串

命令说明
set key value 存入或修改键值对
get key 根据键取出值
incr key 自增
decr key 自减
del key 根据键删除值
setex key timeout value 存入或修改键值对,并设置过期时间
ttl key 查询 key 的过期时间,-1为无过期时间,-2为已失效
setnx key value 存入键值对,如果已存在,则不做操作
incrby key num 将当前的值增加 num
decrby key num 将当前的值减少 num
mset k1 v1 k2 v2 … 批量存入或修改键值对
mget k1 k2 … 批量获取键值对
append key value 尾部追加值
setrange key index value 在当前字符串的指定位置增加

Hash 表

命令说明
hset key hashkey hashvalue 设置一个 hash 对象的键值对
hget key hashkey 根据 hash 对象的键获取值
hexists key hashkey 判断这个 hash 对象是否有这个键
hdel key hashkey 根据 hashkey 删除某个 hash 键值对
hincrby key hashkey 递增 hash 的值
hlen key 获取 hash 对象 key 的数量
hkeys key 获取 hash 对象的所有的键
hvals key 获取 hash 对象的所有的值
hgetall key 获取 hash 对象的所有数据
hsetnx key hashkey hashvalue 存入一个 hash 对象的键值对,如果有则不做操作

List 列表

命令用法
rpush/lpush key value 往列表右/左边添加数据
lrange key start end 范围显示列表数据,全显示则设置0 -1
lpop/rpop key 弹出列表最左/右边的数据
llen key 获取列表长度
linsert key before/after refVal value 参考值之前/后插入数据
lset key index value 根据索引修改数据
lrem key count value 在列表中按照个数删除数据
ltrim key start end 范围截取列表
lindex key index 根据索引获取列表数据

Set 无序集合

命令用法
sadd key value 往 set 集合中添加元素
smembers key 列出 set 集合中的元素
srem key value 删除 set 集合中的元素
spop key count 随机弹出集合中的元素
sdiff key1 key2 返回 key1 中特有元素(差集)
sinter key1 key2 返回两个 set 集合的交集
sunion key1 key2 返回两个 set 集合的并集
sdiffstore/sinterstore/sunionstore var k1 k2 取交集/并集/差集后,将返回值放到另一个 set 里
smove key1 key2 value 把 key1 中的某元素移入 key2 中
scard key 返回set集合中元素个数
sismember key value 判断集合是否包含某个值
srandmember key count 随机获取 set 集合中元素

zSet 集合

命令用法
zadd key score value 存入分数和名称
zincrby key score column 偏移名称对应的分数
zrange key start end 按照分数升序输出名称
zrevrange key start end 按照分数降序输出名称
zrank key name 升序返回排名
zrevrank key name 降序返回排名
zcard key 返回元素个数
zrangebyscore key min max [withscores] 按照分数范围升序输出名称
zrevrangebyscore key max min [withscores] 按照分数范围降序输出名称
zrem key name 删除名称和分数
zremrangebyscore key min max [withscores] 根据分数范围删除元素
zremrangebyrank key start end 根据排名删除元素
zcount key min max 按照分数范围统计个数

事务

命令用法
multi 开启事务
exec 提交事务
discard 取消事物

其他高级命令

命令用法
keys name 查询所有的 key 名,可以用 * 模糊查询
exists key 查询是否存在 key
expire key 设置某个 key 的过期时间
persist key 取消 key 的过期时间
flushdb/flushall 清空当前库/清空所有库
select number 选择库(0~15)
move key index 将 key 移动到第 index 个数据库
randomkey 随机返回数据库中的key
rename key newkey 重命名
dbsize 查看数据库的key数量
**info ** 获取数据库信息
**config get ** 实时传储收到的请求(返回相关的配置信息)
**config get * ** 返回所有配置

理论部分

选择数据类型的原则

如果确定使用redis, 此时需要考虑使用哪个数据类型

  • 如果要排序选用 zset
  • 如果数据是多个且允许重复选用 list
  • 如果数据是多个且不允许重复选用 set
  • 剩下的使用 string
  • 如果是对象类型也可使用hash
  • 有些公司约定: 所有的 redis 的 key 跟 value 都使用字符串,如果使用排序,就用 zset,因为这样:

    • 可以避免泛型的使用
    • 方便转换字符串

    Key 的设计

    key的设计:

  • 唯一性
  • 可读性
  • 灵活性
  • 时效性
  • 持久化机制

    RDB

    默认方式。将内存中以快照的方式写入到二进制文件中.默认为dump.rdb。可以配置设置自动做快照持久化方式。我们可以配置 redis 在 n 秒内如果超过 m 个 key 就修改自动做快照。

    执行 save 命令,或 flushdb/flushalll 命令时,会直接触发 RDB

    save 900 1 #900秒内如果超过1个Key被修改则发起快照保存
    save 300 10
    save 60 10000

    AOF

    aof比快照方式有更好的持久化性,是由于在使用aof时,redis会将每一个收到的写命令都通过write函数追加到命令中,当redis重新启动时会重新执行文件中保存的写命令来在内存中重建这个数据库的内容.这个文件在bin目录下:appendonly.aof

    appendonly yes //启动aof持久化方式有三种修改方式
    #appendfsync always//收到命令就立即写到磁盘,效率最慢.但是能保证完全的持久化
    #appendfsync everysec//每秒写入磁盘一次,在性能和持久化方面做了很好的折中
    #appendfsync no //完全以依赖os 性能最好,持久化没保证

    总结
    • RDB 性能好,但是易丢失数据
    • AOF 性能差,但是不易丢失数据

    内存淘汰机制

    常见的内存淘汰机制分为四大类:

    1. LRU:LRU是Least recently used,最近最少使用的意思,简单的理解就是从数据库中删除最近最少访问的数据,该算法认为,你长期不用的数据,那么被再次访问的概率也就很小了,淘汰的数据为最长时间没有被使用,仅与时间相关。

    2. LFU:LFU是Least Frequently Used,最不经常使用的意思,简单的理解就是淘汰一段时间内,使用次数最少的数据,这个与频次和时间相关。

    3. TTL:Redis中,有的数据是设置了过期时间的,而设置了过期时间的这部分数据,就是该算法要解决的对象。如果你快过期了,不好意思,我内存现在不够了,反正你也要退休了,提前送你一程,把你干掉吧。

    4. 随机淘汰:生死有命,富贵在天,是否被干掉,全凭天意了。

    Key 删除策略

    Redis中大家会对存入的数据设置过期时间,那么这些数据如果过期了,Redis是怎么样把他们消灭掉的呢?我们一起来探讨一下。下面介绍三种清除策略:

    • 惰性删除:当访问Key时,才去判断它是否过期,如果过期,直接干掉。这种方式对CPU很友好,但是一个key如果长期不用,一直存在内存里,会造成内存浪费。

    • 定时删除:设置键的过期时间的同时,创建一个定时器,当到达过期时间点,立即执行对Key的删除操作,这种方式最不友好。

    • 定期删除:隔一段时间,对数据进行一次检查,删除里面的过期Key,至于要删除多少过期Key,检查多少数据,则由算法决定。举个例子方便大家理解:Redis每秒随机取100个数据进行过期检查,删除检查数据中所有已经过期的Key,如果过期的Key占比大于总数的25%,也就是超过25个,再重复上述检查操作。

    集成 Java 应用

    Jedis

    导入依赖:

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

    基本操作

    // 创建Jedis连接池
    JedisPool pool = new JedisPool("localhost", 6379);
    // 从连接池中获取Jedis对象
    Jedis jedis = pool.getResource();
    jedis.auth("123456"); // 密码
    // TODO: 执行逻辑
    System.out.println(jedis);
    // 关闭资源,销毁连接池
    jedis.close();
    pool.destroy();

    细节配置

    GenericObjectPoolConfig config = new GenericObjectPoolConfig();
    //最大连接数, 默认8个
    config.setMaxTotal(100);
    //最大空闲连接数, 默认8个
    config.setMaxIdle(20);
    //获取连接时的最大等待毫秒数(如果设置为阻塞时BlockWhenExhausted),如果超时就抛异常, 小于零:阻塞不确定的时间, 默认-1
    config.setMaxWaitMillis(1);
    //在获取连接的时候检查有效性, 默认false
    config.setTestOnBorrow(true);
    JedisPool pool = new JedisPool(config,"192.168.122.128",6379,5000,"wolfcode");
    Jedis j = pool.getResource();
    String name = j.get("name");
    System.out.println(name);
    j.close();
    pool.close();
    pool.destroy();

    之后调用的方法名同以上命令名

    集成 SpringBoot

    导入依赖:

    <!– SpringBoot 父类 –>
    <parent>
    <artifactId>spring-boot-starter-parent</artifactId>
    <groupId>org.springframework.boot</groupId>
    <version>2.3.3.RELEASE</version>
    </parent>
    <!– SpringBoot 集成 redis –>
    <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
    </dependency>
    <!– SpringBoot 测试 –>
    <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-test</artifactId>
    </dependency>

    application.yml

    spring:
    redis:
    host: 127.0.0.1
    port: 6379
    password:

    基本操作

    @Autowired
    private StringRedisTemplate redisTemplate;

    @Test
    public void testRedisTemplate() {
    // 操作string
    redisTemplate.opsForValue().set("name", "LTT");
    // 操作hash
    redisTemplate.opsForHash().put("user", "name", "LTT");
    // 操作list
    redisTemplate.opsForList().leftPush("hobby", "唱");
    // 操作set
    redisTemplate.opsForSet().add("颜色", "红", "黄", "蓝");
    // 操作zset
    redisTemplate.opsForZSet().add("名单", "小明", 100);
    }

    赞(0)
    未经允许不得转载:171主机测评 » Redis 笔记
    分享到: 更多 (0)

    评论 抢沙发

    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址