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

2020-02-27  本文已影响0人  FredWorks

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 来操作字符串数据。

    public String get(String key) {
        ValueOperations<String, String> opsForValue = this.stringRedisTemplate.opsForValue();
        return Optional
                .ofNullable(opsForValue.get(key))
                .orElse("");
    }
    public List<String> multiGet(List<String> keys) {
        ValueOperations<String, String> opsForValue = this.stringRedisTemplate.opsForValue();
        return Optional
                .ofNullable(opsForValue.multiGet(keys))
                .orElse(Collections.emptyList());
    }
    public void set(String key, String value) {
        this.stringRedisTemplate.opsForValue().set(key, value);
    }
    public void set(String key, String value, int expire) {
        this.redisTemplate.opsForValue().set(key, value, Duration.of(expire, ChronoUnit.SECONDS));
    }
    public void setIfAbsent(String key, String value) {
        this.redisTemplate.opsForValue().setIfAbsent(key, value);
    }
    public void multiSet(Map<String, String> values) {
        ValueOperations<String, String> opsForValue = this.stringRedisTemplate.opsForValue();
        opsForValue.multiSet(values);
    }
    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 的操作如下:

    public Map<String, String> get(String key) {
        HashOperations<String, String, String> opsForHash = this.stringRedisTemplate.opsForHash();
        return Optional
                .ofNullable(opsForHash.entries(key))
                .orElse(Collections.emptyMap());
    }
    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());
    }
    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());
    }
    public void set(String key, Map<String, String> entire) {
        HashOperations<String, String, String> opsForHash = this.stringRedisTemplate.opsForHash();
        opsForHash.putAll(key, entire);
    }
    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 中某个值的操作如下:

    public String get(String key, String hashKey) {
        HashOperations<String, String, String> opsForHash = this.stringRedisTemplate.opsForHash();
        return Optional
                .ofNullable(opsForHash.get(key, hashKey))
                .orElse("");
    }
    public void set(String key, String hashKey, String value) {
        HashOperations<String, String, String> opsForHash = this.stringRedisTemplate.opsForHash();
        opsForHash.put(key, hashKey, value);
    }
    public void setIfAbsent(String key, String hashKey, String value) {
        HashOperations<String, String, String> opsForHash = this.stringRedisTemplate.opsForHash();
        opsForHash.putIfAbsent(key, hashKey, value);
    }
    public void delete(String key, String hashKey) {
        HashOperations<String, String, String> opsForHash = this.stringRedisTemplate.opsForHash();
        opsForHash.delete(key, hashKey);
    }
    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

上一篇 下一篇

猜你喜欢

热点阅读