美文网首页
2020-02-17 Redis使用简单总结

2020-02-17 Redis使用简单总结

作者: FredWorks | 来源:发表于2020-02-27 23:55 被阅读0次

1、安装

开发环境使用docker来安装redis。

  1. 首先,搜索redis的官方镜像
docker search redis

搜索结果的第一行就是了:

[root@fedora ~]# docker search redis
NAME                             DESCRIPTION                                     STARS               OFFICIAL            AUTOMATED
redis                            Redis is an open source key-value store that…   7815                [OK]                
bitnami/redis                    Bitnami Redis Docker Image                      136                                     [OK]
sameersbn/redis                                                                  79                                      [OK]
grokzen/redis-cluster            Redis cluster 3.0, 3.2, 4.0 & 5.0               63                                      
rediscommander/redis-commander   Alpine image for redis-commander - Redis man…   34                                      [OK]
kubeguide/redis-master           redis-master with "Hello World!"                31                                      
redislabs/redis                  Clustered in-memory database engine compatib…   24                                      
redislabs/redisearch             Redis With the RedisSearch module pre-loaded…   20                                      
arm32v7/redis                    Redis is an open source key-value store that…   20                                      
oliver006/redis_exporter          Prometheus Exporter for Redis Metrics. Supp…   18                                      
webhippie/redis                  Docker images for Redis                         10                                      [OK]
redislabs/redisgraph             A graph database module for Redis               9                                       [OK]
s7anley/redis-sentinel-docker    Redis Sentinel                                  9                                       [OK]
bitnami/redis-sentinel           Bitnami Docker Image for Redis Sentinel         9                                       [OK]
insready/redis-stat              Docker image for the real-time Redis monitor…   9                                       [OK]
arm64v8/redis                    Redis is an open source key-value store that…   8                                       
redislabs/redismod               An automated build of redismod - latest Redi…   6                                       [OK]
centos/redis-32-centos7          Redis in-memory data structure store, used a…   4                                       
circleci/redis                   CircleCI images for Redis                       3                                       [OK]
frodenas/redis                   A Docker Image for Redis                        2                                       [OK]
tiredofit/redis                  Redis Server w/ Zabbix monitoring and S6 Ove…   1                                       [OK]
runnable/redis-stunnel           stunnel to redis provided by linking contain…   1                                       [OK]
wodby/redis                      Redis container image with orchestration        1                                       [OK]
cflondonservices/redis           Docker image for running redis                  0                                       
xetamus/redis-resource           forked redis-resource                           0                容器                       [OK]
  1. 安装redis容器
    redis是一个内存key-value数据库。使用如下命令默认安装,是安装没有启用存储的实例:
$ docker run --name some-redis -d redis

从 redis 镜像创建一个名字叫 “some-redis” 的容器,不启用存储。

如果要安装有存储的实例,则参照如下命令:

docker run -v /docker/redis/conf:/usr/local/etc/redis -v /docker/redis/data:/data -p 6379:6379 --name redis -d redis redis-server --appendonly yes
  • --name redis -d redis: 从镜像 redis 创建容器,名字也叫redis
  • -v /docker/redis/conf:/usr/local/etc/redis: 这是将本地的 /docker/redis/conf 目录映射到redis容器的 /usr/local/etc/redis 目录;后者是redis配置文件所在目录
  • -v /docker/redis/data:/data 将本地的 /docker/redis/data 目录映射到 redis容器的 /data 目录,这是redis容器存储数据的目录
  • redis-server
  • --appendonly yes: 使用AOF(日志追加模式)存储数据。

关于redis的 RDB存储模式和AOF存储模式的优缺点,就不在这里描述了。大家自行阅读官网文章《Redis Persistence》

2、Redis与Memcache的简单对比

Redis 和 Memcache 都是key-value高速存储,他们有类似也有差异。简单来说如下:

Redis Memcache
类型 key-value 内存数据库,支持存储 key-value 内存缓存,不能存储
灾难恢复 支持,有RBD模式和AOF模式存储,节点挂掉可以恢复 不支持,节点挂掉数据就丢失了
主从复制 支持 本身不支持,但有第三方的magent来实现
数据结构 string、hash、list、set、sorted set 字符串、图片、文件、视频
内存使用 实时申请内存,支持虚拟内存,内存用完后可交换数据到磁盘 根据配置申请内存,不能超过内存限制
数据一致性 支持简单事务,实际上并不可靠 通过CAS确保数据一致
性能对比 使用单核,单条数据100k以下时性能好于memcache 使用多核,单条数据超过100k时性能好于Redis

3、Redis支持的数据结构

这里主要介绍 redis 的每种数据结构和其支持的主要操作,并针对每种主要操作,基于spring-data-redis提供的默认 StringRedisTemplate 进行操作举例。

由于 RedisTemplate 默认假设使用的 key 和 value,都是 Object,其提供的所有接口,都自动进行了 redis 中字符串到对象的转换。
但实际上,个人并不推荐直接在存取 redis 时依赖 RedisTemplate 进行转换,而是 key 和 value 都作为字符串(其在 redis 中时的原始的样子)来存取。至于这个字符串在业务上是否是一个对象序列化而来,由业务来处理。RedisTemplate 作为一个操作 Redis 的工具,还是不要涉及这种业务行为为好。
好在 spring-boot + spring-data-redis 的环境中,spring-boot 默认除了提供基于Object 的 RedisTemplate 的实例 redisTemplate 外,还提供了基于 string 的 StringRedisTemplate 的实例 stringRedisTemplate。后面的所有例子,都是基于 StringRedisTemplate 来实现的。

3.1 字符串格式

缓存数据是一个字符串。一个key对应一个value。

在memcached中,所有的值都是字符串。如果要缓存对象,则需要在存储前,先将对象序列化为字符串再缓存;在取出后,先将数据组装成对象后再使用。
在redis中,我们仍然可以继续这么做。只不过,redis有hash类型,可以更好的支持缓存对象。

下面使用 spring-boot 的默认 stringRedisTemplate 来操作字符串数据。

  • 读取key对应的字符串 (redis指令get):对应值存在,则返回;对应值不存在,则返回 null
    public String get(String key) {
        ValueOperations<String, String> opsForValue = this.stringRedisTemplate.opsForValue();
        return Optional
                .ofNullable(opsForValue.get(key))
                .orElse("");
    }
  • 读取多个key对应的字符串 (redis指令mget):返回List,结果的顺序和key的顺序一样
    public List<String> multiGet(List<String> keys) {
        ValueOperations<String, String> opsForValue = this.stringRedisTemplate.opsForValue();
        return Optional
                .ofNullable(opsForValue.multiGet(keys))
                .orElse(Collections.emptyList());
    }
  • 缓存字符串(redis 指令set):对应key存在,则将缓存的值直接更新为给定的新值;对应key不存在,则新增。
    public void set(String key, String value) {
        this.stringRedisTemplate.opsForValue().set(key, value);
    }
  • 缓存字符串并指定过期时间 (redis指令set):set 的重载方法,只是多个了指定过期时长的 Duration 参数。
    public void set(String key, String value, int expire) {
        this.redisTemplate.opsForValue().set(key, value, Duration.of(expire, ChronoUnit.SECONDS));
    }
  • 如果不存在则缓存 setIfAbsent:顾名思义,只有对应key不存在时,才写入缓存。
    public void setIfAbsent(String key, String value) {
        this.redisTemplate.opsForValue().setIfAbsent(key, value);
    }
  • 缓存多个字符串 multiSet:使用 Map 作为参数,同时缓存多个字符串。
    public void multiSet(Map<String, String> values) {
        ValueOperations<String, String> opsForValue = this.stringRedisTemplate.opsForValue();
        opsForValue.multiSet(values);
    }
  • 返回旧值并更新为新值(redis指令getset):先获取旧值,然后在更新为新值后,返回旧值。
    public String getAndSet(String key, String value) {
        ValueOperations<String, String> opsForValue = this.stringRedisTemplate.opsForValue();
        return Optional
                .ofNullable(opsForValue.getAndSet(key, value))
                .orElse("");
    }

3.2 哈希 hash

缓存的数据结构是一个hash,可以看作Java的一个HashMap。一个key对应的一个HashMap。
由于缓存的是一个HashMap,因此可以操作整个hash,也可以操作hash中某个hash key对应的值。

  • HashMap 中的key,仍然是一个字符串,但 RedisTemplate 返回的是一个Object。这是因为这个key,可能也是一个对象的序列化字符串。为了简化操作,我们一般在对redis进行操作前,先将用作hash key的对象序列化为字符串了。
  • redis对hash 中的 value只能是字符串,不再继续支持级联嵌套 hash了。我们可以将对象序列化为字符串后,作为 hash 的值处理,但无法再多一层。

下面使用 spring-boot 的默认 stringRedisTemplate 来操作 hash 数据。

3.2.1 涉及整个 hash 的操作如下:

  • 获取key对应的整个hash:
    public Map<String, String> get(String key) {
        HashOperations<String, String, String> opsForHash = this.stringRedisTemplate.opsForHash();
        return Optional
                .ofNullable(opsForHash.entries(key))
                .orElse(Collections.emptyMap());
    }
  • 获取 key 对应的 hash 中所有的列:
    public List<String> getAll(String key, Collection<String> hashKeys) {
        HashOperations<String, String, String> opsForHash = this.stringRedisTemplate.opsForHash();
        return Optional
                .ofNullable(opsForHash.values(key))
                .orElse(Collections.emptyList());
    }
  • 获取 key 对应的 hash 中,多个 hash key 对应的列:
    public List<String> multiGet(String key, Collection<String> hashKeys) {
        HashOperations<String, String, String> opsForHash = this.stringRedisTemplate.opsForHash();
        return Optional
                .ofNullable(opsForHash.multiGet(key, hashKeys))
                .orElse(Collections.emptyList());
    }
  • 缓存 key 对应的整个hash:将 entire 中的所有属性缓存到 key 对应的 hash 中去。
    public void set(String key, Map<String, String> entire) {
        HashOperations<String, String, String> opsForHash = this.stringRedisTemplate.opsForHash();
        opsForHash.putAll(key, entire);
    }
  • 获取 key 对应的 hash 中所有的 hash key:
    public Set<String> keys(String key) {
        HashOperations<String, String, String> opsForHash = this.stringRedisTemplate.opsForHash();
        return Optional
                .ofNullable(opsForHash.keys(key))
                .orElse(Collections.emptySet());
    }

3.2.2 涉及 hash 中某个值的操作如下:

  • 获取 key 对应 hash 中某个 hash key 对应的值:key或 hash key 不存在时返回null
    public String get(String key, String hashKey) {
        HashOperations<String, String, String> opsForHash = this.stringRedisTemplate.opsForHash();
        return Optional
                .ofNullable(opsForHash.get(key, hashKey))
                .orElse("");
    }
  • 缓存一个字符串到 key 对应的 hash 中 hash key 对应的列
    public void set(String key, String hashKey, String value) {
        HashOperations<String, String, String> opsForHash = this.stringRedisTemplate.opsForHash();
        opsForHash.put(key, hashKey, value);
    }
  • 仅当hash key对应的列不存在时缓存字符串
    public void setIfAbsent(String key, String hashKey, String value) {
        HashOperations<String, String, String> opsForHash = this.stringRedisTemplate.opsForHash();
        opsForHash.putIfAbsent(key, hashKey, value);
    }
  • 删除 key 对应的 hash 中 hash key 对应的列
    public void delete(String key, String hashKey) {
        HashOperations<String, String, String> opsForHash = this.stringRedisTemplate.opsForHash();
        opsForHash.delete(key, hashKey);
    }
  • 检查 key 对应的 hash 中某个 hash key 是否存在:
    public boolean hasHashKey(String key, String hashKey) {
        HashOperations<String, String, String> opsForHash = this.stringRedisTemplate.opsForHash();
        return opsForHash.hasKey(key, hashKey);
    }

3.3 TODO 链表 list

3.4 TODO 集合 set

3.5 TODO 有序列表 zset

相关文章

  • 2020-02-17 Redis使用简单总结

    1、安装 开发环境使用docker来安装redis。 首先,搜索redis的官方镜像 搜索结果的第一行就是了: 安...

  • Redis知识总结

    最近参与了一些项目,其中包含单点登陆(集群),因为使用的redis,所以这里简单对redis做一个学习总结,rei...

  • 基于redis、fastapi、websokcet 实现的客服聊

    说明 使用redis存储消息,代码简单,自行阅读参考redis 使用异步库 aredis

  • Redis一致性hash算法

    一、Redis集群的使用 我们在使用Redis的时候,为了保证Redis的高可用,提高Redis的读写性能,最简单...

  • redis使用

    Redis的使用 一、Redis下载 redis的使用很简单,首先需要下载redis,在本机上或者是在远程服务器上...

  • Redis简单总结

    一. Nosql数据库是什么?not only sql,非关系型数据库。这些类型的数据存储不需要固定的模式,无需多...

  • Docker | redis集群部署实战

    前面已经简单熟悉过redis的下载安装使用,今天接着部署redis集群(cluster),简单体会一下redis集...

  • redis简单使用

    set List Hashes 无序集合 有序集合

  • redis简单使用

    redis 默认16个库,编号 0~15,默认为0 SELECT 0选择第0个库,key * 查看改库里的键值 r...

  • redis简单使用

    title: redis简单使用date: 2018-03-07 13:57:10tags: [python,re...

网友评论

      本文标题:2020-02-17 Redis使用简单总结

      本文链接:https://www.haomeiwen.com/subject/gjdwfhtx.html