1.安装 Redis
此处的 Redis 安装是针对 Linux 版本的安装, 因为 Redis 官方没有提供 Windows 版本, 只提供了 Linux 版本. 但是我们可以通过Windows 去远程连接 Redis.
1.1 使用 yum 安装 Redis
使用如下命令, 将 Redis 安装到 Linux 服务器:
yum -y install redis
1.2 启动 Redis
使用如下命令, 以后台运行的方式启动 Redis:
redis-server /etc/redis.conf &
/etc/redis.conf 表示使用 Redis 默认的配置文件
& 表示后台运行
做了这两个步骤之后, 就可以在本地远程操控 Redis 了, 不过需要修改配置文件, 1.4 演示.
1.3 操作 Redis
使用如下命令启动 Redis 客户端 :
redis-cli
这个操作就相当于在 Linux 上启动数据库客户端的命令 mysql -uroot 一样.
具体操作演示 >>
 
   1.4 设置远程连接
- 将 Redis 配置文件下载到本地. 该配置文件为 Linux 下的 /etc/redis.conf. 
 
   1. 先 cd 到 Redis 配置文件的路径下.
2. 使用 sz 命令, 将文件下载到本地.
- 将 redis.conf 中的 "bind 127.0.0.1" 注释掉. 
使用 VSCode 将配置文件打开, Ctrl f 搜索 "bind 127.0.0.1" >>
 
   - 将 redis.conf 中的 :"protected-mode yes" 改为 "protected-mode no". 
 
   - 将修改后的 redis.conf 上传至 Linux 下的 /etc 目录. 
1. rm -rf redis.conf -> 删除旧的配置文件
2. 将本地更新的配置文件拖拽到 xshell 中.
- 使用命令 "redis-cli shutdown" 先关闭 redis 服务, 再使用 "redis-server /etc/redis.conf &" 启动 redis 服务. 
2. 安装 Redis 可视化工具
- 下载链接 : AnotherRedisDesktopManager 
- 安装好了之后, 先把 6379 端口放开 (云服务器里没有值钱的东西) : 
 
   - 打开可视化工具, 新建一个连接. 
 
   1. Host 填自己云服务器的外网IP.
2. Port 填写 6379.
当连接建立成功之后, 我们在 redis 默认的数据库中可以看到刚才创建的键值对 username - zhangsan,
也可以在可视化界面操作 Redis 了.
 
   通过命令操作 Redis 的官方文档 : https://redis.io/commands/
3. Redis 的数据类型和使用
Redis 有 5 大基础类型 >>
1. String - 字符串类型
2. Hash - 字典类型
3. List - 列表类型
4. Set - 集合类型
5. ZSet - 有序集合类型
这其中最常用的就是 字符串类型 和 字典类型.
3.1 字符串类型
Redis 中的字符串类型, 也叫作简单动态字符串, 它是以键值对 key-value 的形式进行存储的.
简单使用示例 >>
 
   使用 ex(expires) 参数设置字符串的过期时间>>
set name zhangsan ex 500 # 设置 name 500s 后过期 (删除)
3.2 字典类型
字典类型 (Hash) 又被成为散列类型或者是哈希表类型,它是将一个键值 (key) 和一个特殊的“哈希表”关联起来,这个“哈希表”表包含两列数据:字段和值,它就相当于 Java 中的 Map<String,Map<String,String>> 结构。
具体结构如下 >>
 
   从图中来看, 使用字典类型来存储键值对信息, 就无须手动序列化和反序列化数据了, 所以使用起来更加高效方便.
简单使用示例 >>
 
   3.3 列表类型
列表类型 (List) 是一个使用链表存储的有序结构, 它元素的插入会按照先后顺序存储到链表结构中, 因此它的插入和删除操作的时间复杂度为 O(1), 当它的查询速度为 O(n).
简单的使用示例 >>
 
   列表的典型使用场景有以下两个:
1. 消息队列:列表类型可以使用 rpush 实现先进先出的功能,同时又可以使用 lpop 轻松的弹出(查询并删除)第一个元素,所以列表类型可以用来实现消息队列;
2. 文章列表:对于博客站点来说,当用户和文章都越来越多时,为了加快程序的响应速度,我们可以把用户自己的文章存入到 List 中,因为 List 是有序的结构,所以这样又可以完美的实现分页功能,从而加速了程序的响应速度。
3.4 集合类型
集合类型 (Set) 是一个无序并唯一的键值集合.
集合类型的简单使用 >>
 
   集合类型(Set)和列表类型(List)的区别:
列表可以存储重复元素,集合只能存储非重复元素;
列表是按照元素的先后顺序存储元素的,而集合则是无序方式存储元素的
3.5 有序集合类型
有序集合类型 (Sort Set) 相比于集合类型多了一个排序属性 score (分数 /权重), 也就是说每个有序集合存储的元素对应两个值, 一个是有序结合的元素值 , 一个是排序值 (权重). 并且有序集合存储的元素也是不能重复的, 但排序值可以重复.
存储结构 >>
 
   4. SpringBoot 集成 Redis
4.1 添加 redis 依赖
 
   4.2 配置 redis
以下是 .properties 的配置.
spring.redis.database=1
spring.redis.port=6379
spring.redis.host=43.139.1.94
spring.redis.lettuce.pool.min-idle=5
spring.redis.lettuce.pool.max-idle=10
spring.redis.lettuce.pool.max-active=8
spring.redis.lettuce.pool.max-wait=1ms
spring.redis.lettuce.shutdown-timeout=100ms
4.3 操作 redis
4.3.1 将字符串存储在 redis 中
@RestController
public class MyRedisController {
    @Autowired
    private StringRedisTemplate stringRedisTemplate;
    // 在 redis 中存储数据
    @RequestMapping("/setstr")
    public String setStr(String key, String value) {
        if(StringUtils.hasLength(key) && StringUtils.hasLength(value)) {
            stringRedisTemplate.opsForValue()
                    .set(key, value);
            return "redis 操作成功.";
        } else {
            return "redis 操作失败.";
        }
    }
    // 从 redis 中读取数据
    @RequestMapping("/getstr")
    public String getStr(String key) {
        String result = null;
        if(StringUtils.hasLength(key)) {
            result = stringRedisTemplate.opsForValue()
                    .get(key);
        }
        return "结果: " + result;
    }
}验证setstr >> 127.0.0.1:8080/setstr?key=test_redis_1&value=Java
 
   验证 getstr >> 127.0.0.1:8080/getstr?key=test_redis_1
 
   客户端查看数据 >>
 
   此处要注意客户端默认连接 redis 的是 DB0, 而前面在配置文件 中设置的数据库是 DB1, 所以客户端在DB0 中看不到数据的.
如果想要使用命令拿到程序中设置的 value, 使用如下命令 >>
1. select 1 -> 切换数据库
2. get test_redis_1 -> 获取值
4.3.2 将对象以字符串形式存储 redis
创建 User 类:
@Data
public class User {
    private int id;
    private String username;
    private String password;
}代码示例 >>
@RestController
public class MyRedisController {
    private User user;
    @Autowired
    private ObjectMapper objectMapper;
    private final String object_redis_key = "user_1";
    @Autowired
    private StringRedisTemplate stringRedisTemplate;
    /**
     * 使用双重校验锁来构建一个单例 User对象
     * @return
     */
    public User getUser() {
        if(user == null) {
            synchronized (this) {
                if(user == null) {
                    user = new User();
                    user.setId(1);
                    user.setUsername("张三");
                    user.setPassword("123");
                }
            }
        }
        return user;
    }
    /**
     * 将对象存储在 redis 中
     * @return
     * @throws JsonProcessingException
     */
    @RequestMapping("/setobj")
    public String setObj() throws JsonProcessingException {
        User user = getUser();
        String userStr = objectMapper.writeValueAsString(user);
        stringRedisTemplate.opsForValue().set(object_redis_key, userStr);
        return "操作成功! ";
    }
    /**
     * 从 redis 中读取对象
     * @return
     * @throws JsonProcessingException
     */
    @RequestMapping("getobj")
    public User getObj() throws JsonProcessingException {
        String userStr = stringRedisTemplate.opsForValue().get(object_redis_key);
        User user = objectMapper.readValue(userStr, User.class);
        return user;
    }
}验证 setobj >>
 
   验证 getobj >>
 
   4.3.3 将对象以字典类型存储 redis
// ... 省略相同代码
private final String object_redis_key2 = "user_2";
@Autowired
private StringRedisTemplate stringRedisTemplate;
/**
 * 将对象以字典类型存储 redis
 * @return
 */
@RequestMapping("/sethash")
public boolean setHash() {
    User user = getUser();
    stringRedisTemplate.opsForHash().put(object_redis_key2, "id", String.valueOf(user.getId()));
    stringRedisTemplate.opsForHash().put(object_redis_key2, "username", user.getUsername());
    stringRedisTemplate.opsForHash().put(object_redis_key2, "password", user.getPassword());
    return true;
}
@RequestMapping("/gethash")
public String getHash() {
    return stringRedisTemplate.opsForHash().get(object_redis_key2, "username").toString();
}验证 setHash >> 127.0.0.1:8080/sethash
 
   验证 getHash >> 127.0.0.1:8080/gethash
 
   以 Hash 的形式存储 redis 的优点 >>
可以单独读取对象中的某一个成员, 不用将整个对象读取出来, 比较节省网络带框.
以 Hash 的形式存储 redis 的缺点 >>
存储对象会非常麻烦, 如果读取数据的时候, 需要将整个对象读出来, 也会非常麻烦.



















