虚拟化技术docker

发布时间:2022-09-18 15:00

  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架构图

虚拟化技术docker_第1张图片

    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 < /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

   

        redis.clients

        jedis

        3.5.2

        com.google.code.gson

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

        2.8.6

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 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持久化,突然断电或关机则不行。此外定期保存,最后几分钟的数据丢失风险大,其冷备优势可保证实时数据传输读取速度。

虚拟化技术docker_第2张图片

 

打开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 < /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            //结束

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

<

....

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 循环脚本。

 

ItVuer - 免责声明 - 关于我们 - 联系我们

本网站信息来源于互联网,如有侵权请联系:561261067@qq.com

桂ICP备16001015号