虚拟化技术docker

  1. 简介

1.1概述

Docker是一个虚拟化平台( 官网https://www.docker.com/),诞生于 2013 年初,基于 Google 公司的 Go 语言进行实现。可以通过虚拟化方式,为应用提供可运行的容器。基于这种方式,可更快地打包、测试以及部署应用程序。

1.2使用原理

1.2.1、更多的使用在Linux系统中,可减少各种配置和依赖:

Linux>>>安装Docker>>>Docker创建精简的镜像系统>>>各个容器中安装部署各种应用服务

1.2.2、运行原理:

Docker客户端依据线程从远程仓库下载依赖和配置到本地镜像系统库中,供各个容器使用。

1.2.3架构图

https://i-blog.csdnimg.cn/blog_migrate/b4e04bd13172a73582419f4a3fdfd0f7.png

    1. Docker详细运行机制

1.3.1、docker pull 执行过程:

1)客户端将指令发送给docker daemon

2)docker daemon 先检查本地images中有没有相关的镜像

3)如果本地没有相关的镜像,则向镜像服务器请求,将远程镜像下载到本地

1.3.2、docker run 执行过程:

1、检查本地是否存在指定的镜像,不存在就从公有仓库下载

2、利用镜像创建并启动一个容器

3、分配一个文件系(简版linux系统),并在只读的镜像层外面挂载一层可读写层

4、从宿主机配置的网桥接口中桥接一个虚拟接口到容器中去

5、从地址池配置一个 ip 地址给容器

6、执行用户指定的应用程序

  1. Docker 核心对象

2.1镜像(Image)

Docker 镜像是一个特殊的文件系统(https://hub.docker.com/),镜像可以打包应用的运行环境以及应用程序,可以通过 Docker 启动这个镜像,进而将应用程序在一个容器中启动运行起来。在 Docker 镜像中,操作系统是高度精简的,镜像中的操作系统还不包含内核,容器都是共享所在的宿主机的内核。所以有时会说容器仅包含必要的操作系统(通常只有操作系统文件和文件系统对象),容器中查看到的 Linux 内核版本与宿主机一致。假如现在理解镜像有些抽象,可以暂时先将其理解为一个安装程序。

2.2容器(Container)

Docker容器可以将其理解为一个运行镜像的载体,镜像(Image)和容器(Container)的关系,就像是光盘和光驱。容器基于镜像创建、启动,然后运行镜像的中的文件。我们常常说使用镜像打包应用程序,使用 Docker 发布、部署应用程序,那么当你的应用成功在 Docker 上运行时,称这个应用就是容器化应用( containerized applications)。

  1. Docker在Linux中安装

3.1 Linux虚拟机环境—VMware Workstation Pro15.5以上版本

3.1.1 准备Linux核心的操作系统:本次使用CentOS

全名为“社区企业操作系统(Community Enterprise Operating System)”,提供长期免费升级和更新服务,自由使用。国内最大的服务器操作系统,现在基本所有的互联网公司后台服务器都采用CentOS。

3.1.2 开启CentOS的Linux虚拟机操作系统

     1、启动虚拟机,默认账号密码为root/root

     2、在系统中右键,打开终端,通过ifconfig指令检查网络,获取虚拟机IP地址

3.1.3 通过MobaXterm工具链接虚拟机系统

     通过获取的IP地址,新建远程连接。

3.2 离线安装Docker

3.2.1下载docker离线包

https://download.docker.com/linux/static/stable/x86_64/docker-20.10.6.tgz

也可以从https://download.docker.com/linux/static/stable/网址下载指定版本

3.2.2下载离线安装工具

    https://github.com/Jrohy/docker-install/

3.2.3将下载好的资源(以下三个文件)放在一个目录

      docker-20.10.6.tgz

      install.sh

docker.bash

3.2.4在linux环境下,创建/root/setup/docker目录,然后拷贝下载好的资源到此目录(可通过MobaXterm工具直接上传到linux目录)

3.2.5 执行安装操作

    # 进入/root/setup/docker 文件夹

cd /root/setup/docker

# 为 install.sh添加执行权限

chmod +x install.sh

# 安装

./install.sh -f docker-20.10.6.tgz 

3.2.6 安装成功后显示

docker 20.10.6 install success!

3.2.7 检查安装状态

docker info

3.3在线安装Docker

3.3.1安装一组工具

      sudo yum install -y yum-utils  // sudo切换到管理员,如果为管理员权限可省略

3.3.2设置 yum 仓库地址

中央库:

sudo yum-config-manager \

     --add-repo \

     https://download.docker.com/linux/centos/docker-ce.repo

镜像库:

sudo yum-config-manager \

     --add-repo \

     http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo

3.3.3更新 yum 缓存

sudo yum makecache fast    #yum 是包管理器

3.3.4安装新版 docker

         sudo yum install -y docker-ce docker-ce-cli containerd.io

4. Docker服务基本操作

4.1启动docker服务:systemctl start docker

4.2查看Docker状态:systemctl status docker

4.3设置Docker开机自启:systemctl enable docker

4.4禁用Docker开机自启:systemctl disable docker

4.5重新启动Docker服务:systemctl restart docker

4.6查看Docker信息:docker info

4.7查看Docker具体key信息:docker info | grep 'Docker Root Dir:'

4.8停止docker服务:systemctl stop docker

4.9 国内网络原因需Docker镜像加速:修改配置文件 /etc/docker/daemon.json

配置文件内容修改为:

cat <<EOF > /etc/docker/daemon.json

{

  "registry-mirrors": [

    "https://docker.mirrors.ustc.edu.cn",

    "http://hub-mirror.c.163.com"

  ],

  "max-concurrent-downloads": 10,

  "log-driver": "json-file",

  "log-level": "warn",

  "log-opts": {

    "max-size": "10m",

    "max-file": "3"

    },

  "data-root": "/var/lib/docker"

}

EOF

5. Docker镜像操作(hello-world文件为例)

5.1下载镜像    :docker pull hello-world

5.2浏览镜像文件:docker images

5.3查看镜像详情:docker inspect hello-world

5.4查看镜像历史:docker history hello-world

5.5导出镜像文件:docker save  hello-world | gzip > hello-world.tar.gz

5.6删除镜像文件:docker image rm hello-world

5.7导入镜像操作:docker load < hello-world.tar.gz  要在被导入的文件所在目录执行

5.8运行镜像文件:docker run hello-world

6. Docker的容器操作(CentOS镜像为例)

6.1下载镜像(Image)

6.1.1  pull指令下载:官方镜像仓库地址为https://hub.docker.com

docker pull centos:7

6.1.2 本地导入

将下载好的centos:7可通过MobaXterm工具直接上传到linux目录

6.1.3查看镜像

docker images

6.2创建并启动容器(Container)

docker run -it xxxx bash

1)xxxx - 镜像名, 或 image id 的前几位,

2)-it 这是两个参数(-i表示交互式操作, -t 表示终端)

3) bash 表示进入操作终端,基于交互式进行相关操作(例如执行linux相关指令)。

6.3查看Docker中的容器(Container)

docker ps 要在宿主机执行docker指令,不能在容器中执行,docker是安装在宿主机的

6.4查看Docker所有容器(Container)

docker ps –a    要在宿主机执行docker指令,-a表示全部(all)

6.4查看容器日志(logs)信息

docker container logs 802  #802为自己的容器id(一般写前三位即可)

6.5停止(stop)或重启(Restart)容器(Container)

停止: docker  container  stop 802  #802为容器自己的id

重启: docker container restart 802 #802位容器自己的id

6.6进入(exec)指定容器(Container)

docker exec -it 802 bash #802为容器id    //容器需要在运行状态

6.7从容器(Container)中退出(exit)

exit

6.8删除(rm)容器(Container)

容器非运行状态 :docker  container  rm 802   #802为容器id,

容器在运行状态(强制) :docker  container  rm  -f  802   #802为容器id

清理所有处于终止状态容器: docker container prune

7. Docker的数据管理

7.1容器中管理数据主要有两种方式

数据卷(Volumes)

挂载主机目录 (Bind mounts)

7.2数据卷

7.2.1什么是数据卷:

数据卷是一个可供一个或多个容器使用的特殊目录,可以在容器之间共享和重用,默认会一直存在,即使容器被删除。

7.2.2数据卷操作

1、创建数据卷

    docker volume create container-vol  // container-vol为宿主机中数据卷名

2、查看所有数据卷

    docker volume ls

3、查看指定 数据卷 的信息

docker volume inspect container-vol

4、启动挂载 数据卷 的容器

docker run -it --mount source=container-vol,target=/root centos:7 bash

或者采用如下简写方式

docker run -it -v container-vol:/root centos:7 bash

container-vol为数据卷名,/root为容器中的挂载目录,如果不存在就会创建

5、删除数据卷(如果数据卷被容器使用则无法删除)

docker volume  rm  container-vol

6、清理无主数据卷

    docker volume  prune

7.3挂载主机目录

在启动容器时,以目录直接挂载的方式进行数据操作

docker run -it -v  /usr/app : /opt/app  centos:7 bash

1)/usr/app:为宿主机目录

2)/opt/app: 为启动容器的一个目录,如果为启动镜像,这一部分一般在镜像文件中有说明

3)-v 用于指定挂载目录,如果本地目录(宿主机目录)不存在, Docker 会自动为你按照挂载目录进行目录的创建。

7.3.1查看挂载目录信息

docker inspect 91a    #91a 为容器id

8. Dockerfile及镜像制作实践

8.1准备工作

centos:7镜像    //因镜像是静态,需要在容器中运行,所以需要本镜像容器 

Dockerfile文件  //类似于配置文件

(jdk-8u51-linux-x64.tar.gz     //在JAVA中运行

sentinel-dashboard-1.8.0.jar)需要往镜像中添加什么就准备相应包

8.2创建Dockerfile文件

拷贝如下代码到你的Dockerfile中

8.2.1创建sentinel镜像所需Dockerfile代码

FROM centos:7

ADD jdk-8u51-linux-x64.tar.gz  /usr/local/

ADD sentinel-dashboard-1.8.0.jar  /usr/local/

ENV JAVA_HOME=/usr/local/jdk1.8.0_51 \

    PATH=/usr/local/jdk1.8.0_51/bin:$PATH

EXPOSE 8080

ENTRYPOINT ["java","-jar","/usr/local/sentinel-dashboard-1.8.0.jar"]  

8.2.2创建java镜像所需Dockerfile代码

FROM centos:7

ADD jdk-8u51-linux-x64.tar.gz /usr/local/docker

ENV JAVA_HOME=/usr/local/docker/jdk1.8.0_51 \

    PATH=/usr/local/docker/jdk1.8.0_51/bin:$PATH

CMD ['bash']

8.3准备就绪后开始构建镜像

docker build -t  sentinel:8 .  #不要丢掉这里的点,-t表示镜像标识(镜像名),是tag单词的缩写.

docker build -t jdk:8 .      #不要丢掉这里的点,-t表示镜像标识(镜像名),是tag单词的缩写.

8.4运行镜像(image)文件

在宿主机中执行,启动JDK容器,运行jdk镜像:docker run -it jdk:8 bash

启动sentinel容器运行sentinel镜像:docker run -d --name sentinel8181 -p 8181:8080 sentinel:8 

#-d 表示后台运行,-p用于指定端口映射,sentinel:8为镜像文件名

9. Docker安装使用数据库

9.1Docker启动mysql镜像的容器

9.1.1本地加载或在线下载mysql

docker pull mysql:8.0.23

9.1.2检查mysql镜像

     docker images

9.1.3启动运行mysql镜像 (docker run 用于启动一个容器)

   sudo docker run -p 3306:3306 --name mysql \                       

-v /usr/local/docker/mysql/mysql-files:/var/lib/mysql-files \

-v /usr/local/docker/mysql/conf:/etc/mysql \

-v /usr/local/docker/mysql/logs:/var/log/mysql \

-v /usr/local/docker/mysql/data:/var/lib/mysql \

-e MYSQL_ROOT_PASSWORD=root \

-d mysql:8.0.23

9.1.4 登陆mysql服务

    进入容器:sudo docker exec -it mysql bash

登陆:mysql -uroot -proot  或者在进如容器时将bash替换为本命令

9.1.5 停止和启动mysql服务

      启动: docker stop mysql

      停止: docker start mysql

      mysql开机自启动:docker update mysql --restart=always

9.2安装启动Redis数据库

9.2.1下载镜像文件

docker pull redis

9.2.2准备配置文件

     创建redis配置文件目录:mkdir -p /usr/local/docker/redis01/conf

     conf目录下创建redis.conf配置文件:touch /usr/local/docker/redis01/conf/redis.conf

9.2.3创建redis实例并启动

    sudo docker run -p 6379:6379 --name redis01 \

-v /usr/local/docker/redis01/data:/data \

-v /usr/local/docker/redis01/conf/redis.conf:/etc/redis/redis.conf \

-d redis redis-server /etc/redis/redis.conf

9.2.4查看redis是否运行

docker ps

9.2.5 访问redis服务器

     控制台直接连接redis测试:docker exec -it redis01 bash

     检测redis 版本:redis-server  -v 或redis-cli –v

     登录redis(默认不需要密码):redis-cli

     或者将上面步骤合为一个步骤执行:docker exec -it redis01 redis-cli

9.2.6停止和启动redis容器服务

     启动:docker start redis01

     停止:docker stop redis01

     重启:docker restart redis01

9.2.7查看启动的redis进程信息

     ps -ef|grep redis

root    3511     1  0 16:29 ?   00:00:01 redis-server *:6379

root    3515     1  0 16:29 ?   00:00:01 redis-server 127.0.0.1:6380

9.2.8 杀死进程

      kill -9

9.2.9登陆远程redis

     redis-cli  -h  ip地址  -p  6379端口号  -a  password密码

9.3 使用Redis

9.3.1基本操作

查看redis信息: info   #查看当前redis节点的详细配置信息

清空redis屏幕:clear   #清除redis屏幕内容

退出redis服务:exit

关闭redis服务:shutdown

系统帮助:help +需要查找的内容

9.3.2 Redis数据存储操作

1、简易数据存取:

查看redis中的key:keys *   // *为所有键

基于key/value形式存储数据:set key  value  //存储后的数据为string形式

基于key/value形式获取数据:get key   //获取到value

2、清除redis中的数据

清除当前数据库数据:flushdb

清除所有数据库数据:flushall

9.3.3 Key有效时间设计EXPIRE key seconds

实际工作中我们经常要控制redis中key的有效时长,例如秒杀操作的计时,缓存数据的有效时长等。

设置有效时长10秒:expire key 10

查询剩余时长:ttl key    //值为-2,表示key不存在, -1表示key存在但无设置时长

设置时长失效:persist  key

9.3.4常用数据类型

     Reids中基础数据结构包含字符串、散列,列表,集合,有序集合。工作中具体使用哪种类型要结合具体场景。

9.3.5 String类型操作:只是数字的String类型才能进行incr/ incrby操作

incr : 从1开始递增

incr num:对num的值进行自增

incrby num 2:对num的值进行加2

decr num:对num的值进行自减:

decrby num 2:对num的值进行减2

append  test  "abc":在value为test的后面拼接abc

strlen  key: 根据key查询value的数据长度,如果key不存在或者无值都会返回0

mset  key1 value1 key2 value2 … : 同时设置多个键值对数据

mget  key1 key2 key3: 同时获取多个键值对数据

9.3.6  Hash类型应用

散列类型相当于Java中的HashMap,实现原理跟HashMap一致,一般用于存储对象信息,存储了字段(field)和字段值的映射,一个散列类型可以包含最多232-1个字段。

HSET key field value :设置map名为key的,字段filed(同key下不可重复)值为value

HGET key field:获取hashmap名为key的,字段filed的所有值

HMSET key field1 value1 field2 value2…:同时设置基于key的多个键值对数据

HMGET key field1 field2:基于key通过多个给定field同时获取的多个键值对数据

HGETALL key:基于key获取所有键值对

hincrby article total -1:对article 下的total的值进行自增

hexists user username:判断username是否存在

hdel user age:删除user的age属性

hkeys user:只获取user集合的字段名

hvals user:只获取user集合的字段值

hlen user:获取user集合的元素个数

9.3.7  List类型应用

lpush mylist "world":mylist集合向头部添加字符串元素

rpush mylist2 "world":mylist集合向尾部添加字符串元素

lrange mylist 0  -1:返回mylist中指定区间元素,0为第一个元素,-1为最后一个元素

del mylist:清空mylist集合元素。

linsert mylist before "world" "there":在world之前添加there

lset  mylist  -2 "five":在mylist集合倒数第二个位置添加five

lrem mylist  2  "hello":数>0时,从头到尾删除2个hello值

lrem mylist  -2  "hello":数<0时,从尾到头删除2个hello值

lrem mylist  0  "hello":数=0时,删除所有hello值

ltrim mylist  1  -1 :保留从下标为1开始到倒数第一个数(含)

lpop mylist:从头开始删除mylist集合中的元素,并返回元素名

rpop mylist:从尾开始删除mylist集合中的元素,并返回元素名

llen mylist:获取集合长度(个数)

lindex mylist 0:获取集合中下标为0的元素

rpoplpush lst1 lst2:移除lst1中最后一个元素到lst2的头部。

9.3.8  set类型应用

srem  set1  c: 移除set1的c元素

sadd name tony:name集合中添加tony //set集合元素不可重复

smembers name:获取name集合中的元素所有//set集合元素随机排列,每次顺序不同

sismember name tony :检查tony是否存在,返回1或0

spop  name: 随机移除name中的一个元素,并返回元素名

scard  name:获取name集合中元素个数

smove set1 set2 a:将set1中的a元素移动到set2中,无序

sunion set1 set2:将set1 和set2集合合并

10安装Nginx代理

11安装nacos

12 Docker容器互联

13 java中操作redis

13.1 jedis

13.1.1 Jedis是什么

    Jedis是Redis官方推出的一款面向Java的客户端,提供了很多接口供Java语言调用, 类似通过jdbc访问mysql数据库。

开始在 Java 中使用 Redis 前, 我们需要确保已经安装了 redis 服务及 Java redis 驱动,且你的机器上能正常使用 Java。

13.1.2 添加依赖Jedis

    <dependency>

        <groupId>redis.clients</groupId>

        <artifactId>jedis</artifactId>

        <version>3.5.2</version>

</dependency>

<dependency>

        <groupId>com.google.code.gson</groupId>

        <artifactId>gson</artifactId>//操作json三剑客之一另外两个是jackson、fastjson

        <version>2.8.6</version>

</dependency>

13.1.2 基本应用

  1获取链接对象:

  Jedis jedis=new Jedis("192.168.126.128",6379); //redis所在ip地址和端口号

  2、看是否能ping通:

String ping = jedis.ping();

3、增删改查基本操作:

增:jedis.set("id", "100");

删:Long name1 = jedis.del("name");//返回被删除的字段名

     System.out.printf("name=%d",name1); //数字占位符为d,字符串占位符为s

改:jedis.incr("id");        //id自增

    jedis.incrBy("id",10);       //id按给定数值增加

查:String id = jedis.get("id");

4、释放资源:

jedis.close();

13.1.3对象转为json串对象组件:gson

创建map集合对象: Map<String, String> userMap = new HashMap<>();

获取gson组件对象:Gson gson = new Gson();

map对象转为json字符串:String json = gson.toJson(userMap);

13.1.4 通过连接池(享元模式)获取数据源链接对象:

    JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();//获取连接池配置

    jedisPoolConfig.setMaxTotal(1000);//配置最大连接数

    jedisPoolConfig.setMaxIdle(60);//配置最大空闲数

jedisPool = new JedisPool(jedisPoolConfig,"192.168.126.128", 6379);//获取连接池

jedisPool.getResource();//获取数据源链接,再通过链接操作数据源

13.1.5 创建全局唯一连接池:

方法一:饿汉式——无论如何都会创建

private static JedisPool jedisPool;

    static {

        JedisPoolConfig jedisPoolConfig=new JedisPoolConfig();

        jedisPoolConfig.setMaxTotal(1000);

        jedisPoolConfig.setMaxIdle(60);

        jedisPool = new JedisPool(jedisPoolConfig,"192.168.126.128", 6379);

    }

    public static Jedis getConnection(){

        return jedisPool.getResource();

    }

    public static  void close(){

        jedisPool.close();

    }

方法二:懒汉式——只在调用时会创建

/*volatile关键字规定属性赋值需要按原顺序执行,禁止重排序
     
可以保证被修饰对象可见性(一个线程修改了值,其他线程可见)
     */
 
private static  volatile  JedisPool jedisPool;
public static Jedis getConnection(){
    if(jedisPool==null){
        synchronized (JedisDataSource.class){ //使用类的字节码对象加锁静态资源等同于将 synchronized加在静态方法上但是加在方法上不能进行双重校验,效率低

            if (jedisPool==null){
                JedisPoolConfig jedisPoolConfig=new JedisPoolConfig();
                jedisPoolConfig.setMaxTotal(1000);
                jedisPoolConfig.setMaxIdle(60);
                jedisPool = new JedisPool(jedisPoolConfig,"192.168.126.128", 6379);
            }
        }
    }
            return  jedisPool.getResource();
}

13.2tempate

本API依赖于spring

13.3springboot整合redis自动缓存原理

spring的CacheAutoConfiguration类通过import注解注入了CacheConfigurationImportSelector,CacheConfigurationImportSelector存在一个自动查找添加缓存组件的方法selectImports,该方法会添加一个SimpleCacheConfiguration类,这个类上有一个默认的CacheManager注解@ConditionalOnMissingBean(CacheManager.class),这个注解默认一个缓存机制,这个注解意思为,当没有缓存组件的时候cacheManager方法才会生效,cacheManager方法管理着ConcurrentMapCacheManager对象,这个对象声明了存储缓存的对象,还可以通过service给定的name 通过这个对象的createConcurrentMapCache方法创建一个新的缓存对象。

而当引入redis后,redis的RedisCacheConfiguration会自动配置取代SimpleCacheConfiguration,类,则spring原有创建缓存对象的机制就会失效,采用redis的缓存机制。

redis组件的序列化方式默认是JdkSerializationRedisSerializer,我们可以通过配置CacheManager将redisCacheManager默认的序列化方案改为Jackson2JsonRedisSerializer或其他。

13.4redis持久化

13.4.1 原因

为了防止突发原因造成缓存丢失。

13.4.2解决方案(aof或rdb(默认))

1、RDB持久化(原理是将Reids在内存中的数据库记录定时dump到磁盘上的RDB持久化)

  主动关机会自动启动RDB持久化,突然断电或关机则不行。此外定期保存,最后几分钟的数据丢失风险大,其冷备优势可保证实时数据传输读取速度。

 

打开redis.conf文件之后,我们搜索save,可以看到下面的配置信息:

save 900 1     #在900秒(15分钟)之后,如果至少有1个key发生变化,则dump内存快照。

save 300 10    #在300秒(5分钟)之后,如果至少有10个key发生变化,则dump内存快照。

save 60 100   #在60秒(1分钟)之后,如果至少有100个key发生变化,则dump内存快照。

2、AOF持久化(原理是将Reids的操作日志以追加的方式写入文件)

 

AOF默认关闭,保存周期短,数据丢失风险低,可记录操作成功的指令但是运行效率会变低。

在Redis的配置文件中存在三种同步方式,它们分别是:

appendfsync always     #每次有数据修改发生时都会写入AOF文件。

appendfsync everysec  #每秒钟同步一次,该策略为AOF的缺省策略。

appendfsync no          #从不同步。高效但是数据不会被持久化。

13.5redis中的事务(同样符合ACID原一隔持四原则)

13.5.1 是什么

是一个业务,也可以看成是一个逻辑工作单元

13.5.2 操作

multi指令:再执行数据库命令时会将命令存储在缓存中,然后执行exec提交事务执行所有(前提是命令和参数不能有错)。discard:取消multi指令

Redis保证一个事务中的所有命令要么都执行,要么都不执行(原子性)。如果在发送EXEC命令前客户端断线了,则Redis会清空事务队列,事务中的所有命令都不会执行。而一旦客户端发送了EXEC命令,所有的命令就都会被执行,即使此后客户端断线也没关系,因为Redis中已经记录了所有要执行的命令。

13.5.3 乐观锁

redis默认为乐观锁,通过监控key的值,如果值发生改变,则基于前数据提交事务会失败。

13.6主从架构设计

13.6.1创建多个redis容器默认都为master

13.6.2 设计从数据库slave

       设置从数据库为slaveof:slaveof +主数据库IP地址+主数据库的端口

13.7主从架构主机维护:Redis哨兵模式

13.7.1作用

被监视的主服务器进入下线状态时,自动将下线主服务器属下的某个从服务器升级为新的主服务器

13.7.2配置

1、每个服务器对应容器的sentinel.conf所在文件夹下执行:

     cat <<EOF > /etc/redis/sentinel.conf   //需要追加的文件

sentinel  monitor  redis6379  172.17.0.2 6379  1  //需要追加的内容

EOF

13.7.2.1 扩展:EOF用法

     执行脚本的时候,需要往一个文件里自动输入N行内容,如果是少数的几行内容,还可以用echo追加方式,如果是很多行可以使用EOF结合cat命令进行行内容的追加。

     EOF表示自定义终止符.既然自定义,那么EOF就不是固定的,可以随意设置别名

其用法如下:

<<EOF        //开始

....

EOF            //结束

还可以自定义,比如自定义:

<<BBB        //开始

....

BBB              //结束

2、每个服务器对应容器的sentinel.conf所在文件夹下执行:启动哨兵服务

redis-sentinel sentinel.conf

13.7.3测试

打开一个新的客户端连接窗口,关闭主机服务(这个服务是master服务)

docker stop redis6379// redis6379这个服务是master服务

不出意外,当为master的主机下线后会随机选取其下的从服务器之一成为master主机。

13.7.4哨兵模式增强配置(根据实际需求修改哨兵模式配置sentinel.conf文件)

sentinel monitor redis6379 172.17.0.2 6379  1 //监听的服务器、IP、端口、认定失效的哨兵数

daemonize  yes #可否后台运行

logfile "/var/log/sentinel_log.log"  # 运行日志

sentinel down-after-milliseconds redis6379 30000 #默认主机失效30秒后更换主机

13.7.5哨兵工作原理

1):每个Sentinel以每秒钟一次的频率向它所知的Master,Slave以及其他 Sentinel 实例发送一个 PING 命令。

2):如果一个实例(instance)距离最后一次有效回复 PING 命令的时间超过 down-after-milliseconds 选项所指定的值(这个配置项指定了需要多少失效时间,一个master才会被这个sentinel主观地认为是不可用的。 单位是毫秒,默认为30秒), 则这个实例会被 Sentinel 标记为主观下线。

3):如果一个Master被标记为主观下线,则正在监视这个Master的所有 Sentinel 要以每秒一次的频率确认Master的确进入了主观下线状态。

4):当有足够数量的 Sentinel(大于等于配置文件指定的值)在指定的时间范围内确认Master的确进入了主观下线状态, 则Master会被标记为客观下线 。

5):在一般情况下, 每个 Sentinel 会以每 10 秒一次的频率向它已知的所有Master,Slave发送 INFO 命令 。

6):当Master被 Sentinel 标记为客观下线时,Sentinel 向下线的 Master 的所有 Slave 发送 INFO 命令的频率会从 10 秒一次改为每秒一次 。

7):若没有足够数量的 Sentinel 同意 Master 已经下线, Master 的客观下线状态就会被移除。

8): 若 Master 重新向 Sentinel 的 PING 命令返回有效回复, Master 的主观下线状态就会被移除。

13.8主从架构升级:集群cluster

13.8.1准备网络环境

创建虚拟网卡,主要是用于集群能于外界进行网络通信,一般常用桥接模式。

docker network create redis-net

查看docker的网卡信息,可使用如下指令

docker network ls

查看docker网络详细信息,可使用命令

docker network inspect redis-net

13.8.2准备redis配置模板 //在宿主机中创建

mkdir -p /usr/local/docker/redis-cluster   //配置文件路径

cd  /usr/local/docker/redis-cluster   //切换到配置文件夹

vim redis-cluster.tmpl              //编辑配置文件

在redis-cluster.tmpl中输入以下内容

port ${PORT}   // port:节点端口,即对外提供通信的端口

cluster-enabled yes/// cluster-enabled:是否启用集群

cluster-config-file nodes.conf// cluster-config-file:集群配置文件

cluster-node-timeout 5000// cluster-node-timeout:连接超时时间

cluster-announce-ip 192.168.126.128// cluster-announce-ip:宿主机ip

cluster-announce-port ${PORT}// cluster-announce-port:集群节点映射端口

cluster-announce-bus-port  1${PORT} // cluster-announce-bus-port:集群总线端口

appendonly yes // appendonly:开启aof持久化模式

13.8.3创建节点配置文件

for port in $(seq 8010 8015); \

do \

  mkdir -p ./${port}/conf  \

  && PORT=${port} envsubst < ./redis-cluster.tmpl > ./${port}/conf/redis.conf \

  && mkdir -p ./${port}/data; \

done

do开始循环,done结束循环,./redis-cluster.tmpl中内容替换掉/${port}/conf/redis.conf内容

——————for 变量 in $(seq var1 var2);do …; done为linux中的一种shell 循环脚本。

 

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值