美文网首页
【Redis学习】Redis Docker安装,自定义confi

【Redis学习】Redis Docker安装,自定义confi

作者: 伊丽莎白2015 | 来源:发表于2022-07-10 20:52 被阅读0次

    【本文内容】

    • 第1章:通过Docker安装Redis,并自定义config文件以及mount data目录。
    • 第2章:介绍Redis持久化到磁盘,有4种方式:RDB / AOF / NONE / RDB + AOF
    • 第3章:使用Server自带的redis-cli工具连接。
    • 第4章:创建Spring Boot项目,通过spring-boot-starter-data-redis进行连接。
    • 第5章:把Spring Boot部署到docker中,测试docker network是否通畅。
    • 第6章:修改redis.conf,RDB持久化以及AOF持久化测试。

    Redis全称:Remote Dictionary Server。是一款开源的Key-Value数据库,运行在内存中,由C语言编写。

    官网:https://redis.com/
    文档:https://redis.io/docs/getting-started/

    Redis还有很多module: image.png

    很多公司用它用为缓存,也有用作database的,还有作为pub/sub(message broker)来使用。

    1. Docker安装

    关于Redis的安装,首先的还是Docker,这样可以和本机环境解耦,无论本机是windows, macos, linux,操作都会一样了。

    【资源】

    【参考】

    如果到时候有app运行在docker中并要连接redis,那么可以先创建网络:

    docker network create redis

    1.1 简单的singleton模式

    运行Docker:

    docker run -it --rm --name redis --net redis -p 6379:6379 redis:latest

    -it 表示run interactively,即通过/bin/bash与容器与行交互。
    --rm 表示让容器在退出时,自动清除挂在的卷,以便清除数据。
    -net 即运行在上述docker network create创建出来的网络中。
    -p 端口,6379为默认端口,如果在远程服务器中,建议不要使用默认端口,主要原因是redis默认是不需要密码的。
    redis:latest表示我们要运行的image=redis,版本为latest(最新版本)

    可以看到下载的最新版本为7.0.2,单机版的redis已经运行了: image.png
    1.2 自定义config

    Redis的核心配置是一个config文件,每个版本可能会不一样,可以从官网上查看:https://redis.io/docs/manual/config/

    我们创建一个文件夹叫redis,在redis文件夹下创建文件夹config,在config中创建一个redis.conf文件,把7.0的config内容放进去:

    image.png

    在redis文件夹下,再次运行Docker,这次使用的是自定义的config

    docker run -it --rm --name redis --net redis -v ${PWD}/config:/etc/redis/ redis:latest redis-server /etc/redis/redis.conf

    ${PWD}表示当前目录
    这里做的是把我们刚刚创建的config目录,mount到docker容器中的/etc/redis/中,config file为/etc/redis/redis.conf,/etc/redis即刚刚mount的文件夹,即运行的redis使用的是我们上述自定义的redis.conf。

    1.3 在redis.conf中启动security

    我们上述说过不要在远程服务器中使用redis的默认端口的主要原因是redis默认是不需要密码登陆的,想要启用密码,可以在#1.2中创建的redis.conf中enable。

    搜索关键字requirepass

    image.png 可以看到默认情况下是不开启的: image.png

    启用需要密码并且把密码设为superpassword

    image.png

    安装redis的时候,可以考虑只在服务器集群内暴露,不要把它暴露到公网中,毕竟一般情况下只有集群内的app需要连接redis。

    2. 持久化

    持久化也是非常重要的一块内容,原因是上述的docker redis如果销毁了,存放在redis server上的数据也就没有了。

    当然生产环境中一般不止一台redis server,假如有3台server,如果其中1台挂了,那么数据还是安全的,但如果3台server都挂了,存放在redis server内存中的数据也就没有了。

    官网:https://redis.io/docs/manual/persistence/

    Redis把数据写到磁盘的方式有:

    • RDB(Redis Database):RDB是以snapshot的方式记录当前的redis server的数据。比如每5分钟dump一个snapshot,存储到磁盘,文件为:dump.rdb。缺点是从最近一次dump到server挂了这段时间的数据会丢失。
    • AOF(Append Only File),将每次server接收的命令append到文件中,文件名叫appendonly.aof,这种方式在同步起来比较快(因为只要append最近的命令即可),但如果真的需要靠它来恢复数据,那么恢复起来就会比较慢一些。

    官网详细的介绍了两者的优缺点:

    除了可以单独选择使用其中的一种持久化方式,还可以选择不持久化,或是两者结合的方式

    【以下是示例】

    2.1 使用RDB的方式进行持久化

    进入我们之前创建的redis.conf文件中,搜索关键字dump

    image.png 可以看到redis默认支持的持久化就是RDB方式,除了可以修改dump后的文件名,我们还可以修改另的关于RDB的参数,如隔多久进行一次snapshot dump等等: image.png
    2.2 使用AOF的方式进行持久化

    搜索关键字append

    image.png

    如果想要打开AOF持久化,可以把no改为yes

    image.png aof的文件名也可以修改: image.png
    2.3 如何选择?

    参考官网:https://redis.io/docs/manual/persistence/#ok-so-what-should-i-use

    • The general indication you should use both persistence methods is if you want a degree of data safety comparable to what PostgreSQL can provide you.
    • If you care a lot about your data, but still can live with a few minutes of data loss in case of disasters, you can simply use RDB alone.
    • There are many users using AOF alone, but we discourage it since to have an RDB snapshot from time to time is a great idea for doing database backups, for faster restarts, and in the event of bugs in the AOF engine.

    官网上说:

    • 如果想要保证数据的安全性,那么就可以同时打开RDB, AOF,即两者相结合的方式。
    • 如果可以容忍一小段时间的数据丢失,那么可以只开RDB(这里的一小段时间指的是RDB的snapshot dump到server down掉的时间)。
    • 有一些用户会只开启AOF,但不建议这样做,因为RDB是backup非常好的一种方式,它恢复数据会非常快,而AOF是基于事件的(即恢复数据靠的是重新run每个event/command),比较慢,而且中间万一哪个事件有点问题,就比较麻烦。
    2.4 创建volumn开始做持久化测试

    首先先创建一个volume叫redis:

    docker volume create redis

    在redis目录下创建data目录: image.png

    在redis目录下运行:

    docker run -it --rm --name redis --net redis -p 6379:6379 -v {PWD}/config:/etc/redis/ -v{PWD}/data:/data/ redis:latest redis-server /etc/redis/redis.conf

    这里我们看到除了mount 当前目录下的config文件夹至docker容器中外,还加了另一个文件夹,即/data。

    以这样方式启动的docker redis,在重启后,里面的数据依然会在。

    3. 使用Server自带的redis-cli工具连接

    使用客户端连接,这里有很多可以选择:

    • server自带的cli命令可以操作数据
    • Java语言的话,可以使用Spring Boot框架可以很方便的连接到客户端
    • 当然别的语言也可以,python, go等

    如果是使用客户端自带的cli工具,可以通过docker exec进入terminal页面,然后输入redis-cli即可,如果有设置过密码的,需要额外输入auth <password>

    image.png 通过cli存放数据以及取出数据: image.png

    4. 使用Spring Boot项目进行连接

    创建一个Spring Boot项目,依赖:

    <?xml version="1.0" encoding="UTF-8"?>
    <project xmlns="http://maven.apache.org/POM/4.0.0"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
        <parent>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-parent</artifactId>
            <version>2.5.7</version>
        </parent>
    
        <dependencies>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-web</artifactId>
            </dependency>
    
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-data-redis</artifactId>
            </dependency>
        </dependencies>
    </project>
    

    创建Main方法:

    @SpringBootApplication
    public class RedisApplication {
        public static void main(String[] args) {
            SpringApplication.run(RedisApplication.class, args);
        }
    }
    

    在application.yaml加上:

    spring:
      redis:
        host: localhost
        port: 6379
        password: superpassword
    

    创建一个Controller:

    @RestController
    public class RedisTestController {
    
        @Autowired
        private RedisTemplate redisTemplate;
    
        @GetMapping("put")
        public boolean put(@RequestParam String key, @RequestParam String value) {
            ValueOperations<String, String> stringRedis = redisTemplate.opsForValue();
            stringRedis.set(key, value);
            return true;
        }
    
        @GetMapping("get")
        public String get(@RequestParam String key) {
            ValueOperations<String, String> stringRedis = redisTemplate.opsForValue();
            return stringRedis.get(key);
        }
    }
    

    启动后发现报错:

    org.springframework.data.redis.RedisConnectionFailureException: Unable to connect to Redis; nested exception is io.lettuce.core.RedisConnectionException: Unable to connect to localhost:6379
    at org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory$ExceptionTranslatingConnectionProvider.translateException(LettuceConnectionFactory.java:1689)

    Caused by: io.lettuce.core.RedisConnectionException: Connection closed prematurely
    at io.lettuce.core.protocol.RedisHandshakeHandler.channelInactive(RedisHandshakeHandler.java:86)

    【需要修改redis.conf】
    protected-mode yes:把yes改为no

    image.png 还需要改下bind: image.png

    重启Redis和Spring Boot App后测试:
    调用put:http://localhost:8080/put?key=testVersion&value=v1.0.0

    image.png get方法: image.png

    5. 把Spring Boot部署到docker中

    5.1 Spring Boot相应改动

    我们打算把Spring Boot项目和Redis放在同一个docker networ中,即在#1创建的redis中。
    所以在application.yaml可以直接用redis来指代host:

    spring:
      redis:
        host: redis
        port: 6379
        password: superpassword
    

    Spring Boot本身package出来的jar需要是可执行的fat jar,所以需要在pom.xml中加上:

        <build>
            <finalName>RedisTest</finalName>
            <plugins>
                <plugin>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-maven-plugin</artifactId>
                </plugin>
            </plugins>
        </build>
    

    mvn clean package打包,打出来的包在项目根目录/target/下。

    5.2 再创建Docker file:
    FROM openjdk:8-jdk-alpine
    COPY target/RedisTest.jar RedisTest.jar
    expose 8080
    ENTRYPOINT ["java","-jar","RedisTest.jar"]
    
    
    5.3 Docker build image

    DockerFile在项目根目录下:

    docker build -f DockerFile -t localhost/redis-test .

    5.4 运行Docker

    这里8081指的是在docker外部即localhost的端口,8080指的是docker容器的端口:

    docker run -p 8081:8080 --net redis --name redis-spring-test localhost/redis-test:latest

    image.png 测试,没有问题: image.png
    5.5 Docker debug

    如果出现connection refused的一些问题,可以进入Spring Boot的终端,然后ping下,看看是否通:

    docker exec -it redis-spring-test /bin/sh

    image.png

    还可以查看#1中通过docker network create redis创建的network是否存在:

    image.png

    6. 测试持久化到磁盘

    6.1 只开启RDB

    我们在#2.1中介绍过,redis默认就是开启RDB的,只是dump的时间需要确定下,从redis.conf中可以看到,如不额外设置时间,默认情况下:

    • 只修改了1个key,1小时同步一次。
    • 修改了100个key,5分钟同步一次。
    • 修改了10000个key,那么1分钟同步一次。
    image.png 为了测试我们可以把同步间隔设短的些,我们把修改1个key后就同步的时间从3600秒改成60秒: image.png

    用#3.4的命令重启Redis(即需要-v mount一个data的目录)后put一个key/value,过60s后check当前redis的data目录:

    可以看到/data下有了dump.rdb文件了: image.png Redis控制台也会打印日志: image.png 那么这时候如果我们把Docker Redis stop了再重启,可以看到会把从dump.rdb中恢复数据,然后这时候运行Spring Boot项目,依旧可以拿到key=testVersion的数据 image.png
    6.2 只开启AOF

    首先是关闭RDB:需要声明save ""

    image.png 再开启AOF,如同#2.2说的,按append关键字搜索,然后把no改为yes: image.png 可以看到对于AOF的同步,有三种方式,第1种是每一次修改,都会调用fsync()。第2种是每隔1秒调用fsync(),第3种是不调用fsync(),由系统控制数据的同步到磁盘。默认是每1各种调用fsync(): image.png 重启Redis后发现持久化已经由之前的RDB改成了AOF: image.png 尝试set一个key/value后: image.png 这时候关闭Redis再重启,可以看到数据会从AOF中恢复,直接get,数据依旧在: image.png

    相关文章

      网友评论

          本文标题:【Redis学习】Redis Docker安装,自定义confi

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