启动mysql的docker镜像,怎么自动执行初始化sql脚本

即使你要把 Docker 数据放在主机来存储 ,它依然不能保证不丢数据。Docker volumes 的设计围绕 Union FS 镜像层提供持久存储,但它仍然缺乏保证。

1、使用ctl 启 ctl start mysqld

docker进入mysql docker进入容器并执行命令docker进入mysql docker进入容器并执行命令


docker进入mysql docker进入容器并执行命令


2、使用脚本启 /etc/inint.d/mysqld start

3、使用safe_m简单地总结就是下面这样ysqld或mysqld --user=mysql

docker中MySQL的时区修改

true

docker中的mysql时区是使用了世界标准时间(UTC),把时区改成东八区方法:

1、启动容器时设置: 添加如‘‘‘下配置:

2、进入docker配置:(重启才能生效--生效)

3、临时修改(从mysql上修改,重启失效)

面试题:如何造10w条测试数据,在数据库插入10w条不同数据

INSERT INTO apps.apiapp_card (id, card_id, card_user, add_time) VALUES (‘3‘, ‘‘, ‘test123‘, ‘2019-12-17‘);

前言

面试题:如果造10w条测试数据,如何在数据库插入10w条数据,数据不重复

最近面试经常会问到sql相关的问题,在数据库中造测试数据是平常工作中经常会用到的场景,一般做压力测试,性能测试也需在数据库中先准备测试数据。那么如何批量生成大量的测试数据呢?

由于平常用python较多,所以想到用python先生成sql,再执行sql往数据库插入数据。

使用语言:python 3.6

插入数据

首先我要插入的 SQL 语句,需每条 id 不重复 ,下面是执行单个插入语句

INSERT INTO apps.apiapp_card (id, card_id, card_user, add_time) VALUES (‘1‘, ‘‘, ‘test123‘, ‘2019-12-17‘);

10w 太多执行时间长,用 python 先生成 1w条测下执行时间。

首先要生成多个inert 语句,这里我用 python 语言写段生成sql的文本。

用 %s 替换需要变的字段值,如果有多个值都需要变,可以用多个%s替换对应值,我这里设计的表,只要id不一样就可以插入成功。

用for 循环,每次循环 id 加1,这样 id 就可以保证不会重复,否则插入数据库时有重复的无法写入成功。

a 是追加写入

每条sql后面分号隔开

每次写入数据,面加

换行

python3

作者:上海-悠悠 QQ群717225969

a = "INSERT INTO apps.apiapp_card (id, card_id, card_user, add_time) VALUES (‘%s‘, ‘‘, ‘test123‘, ‘2019-12-17‘);"%str(i+1)

with open("a.txt", "a") as fp:

fp.write(a+"

")

执行python代码,在本地生成一个 a.text 文件,打开生成的数据,部分如下

INSERT INTO apps.apiapp_card (id, card_id, card_user, add_time) VALUES (‘1‘, ‘‘, ‘test123‘, ‘2019-12-17‘);

INSERT INTO apps.apiapp_card (id, card_id, card_user, add_time) VALUES (‘2‘, ‘‘, ‘test123‘, ‘2019-12-17‘);

INSERT INTO apps.apiapp_card (id, card_id, card_user, add_time) VALUES (‘4‘, ‘‘, ‘test123‘, ‘2019-12-17‘);

......

INSERT INTO apps.apiapp_card (id, card_id, card_user, add_time) VALUES (‘10000‘, ‘‘, ‘test123‘, ‘2019-12-17‘);

如果id是手机号呢,如何生成10w个不同手机号?

可以按手机号前3位开头的号码段生成,比如186开头的,先用初始数据 1860000000,再这个数字基础上每次加1

加到 18600099999,这样号码段1860000000-18600099999就是10w个手机号了。

把id换成手机号后,修改代码如下

python3

作者:上海-悠悠 QQ群717225969

a = "INSERT INTO apps.apiapp_card (id, card_id, card_user, add_time) VALUES (‘%s‘, ‘‘, ‘test123‘, ‘2019-12-17‘);"%str(i+1860000000)

with open("a.txt", "a") as fp:

fp.write(a+"

")

只需在上面基础上把 str(i+1) 改成 str(i+1860000000) 就可以生成手机号了

INSERT INTO apps.apiapp_card (id, card_id, card_user, add_time) VALUES (‘1860000001‘, ‘‘, ‘test123‘, ‘2019-12-17‘);

INSERT INTO apps.apiapp_card (id, card_id, card_user, add_time) VALUES (‘1860000002‘, ‘‘, ‘test123‘, ‘2019-12-17‘);

把生成的文本出来 ,多个INSERT INTO 对应的 sql 一次性贴到 nicat 客户端执行

执行完成花了5分钟左右,也就是说10w条得50分钟,这太慢了,要是数据更多,会等太久,不是我们想要的效果!

批量执行

由于单个执行,花费时间太长,现在需要优化下改成一个 inert 语句,改成批量插入数据,只写一个 insert into 这样一次性批量写到数据库,会快很多。

可以将SQL语句进行拼接,使用 insert into table () values (),(),(),()然后再一次性插入。

批量执行要么全部成功,要么一个都不会写入成功,当写的 SQL 语法有问题时就不会写入成功了。

需注意:

拼接 sql ,多个values 值中间用英文逗号隔开

value 值要与数据表的字段一一对应

一定要注意一条数据后面不是逗号,改成分号

python3

作者:上海-悠悠 QQ群717225969

insert_sql = "INSERT INTO apps.apiapp_card VALUES "

with open("b.txt", "a") as fp:

")

a = "(‘%s‘, ‘‘, ‘test123‘, ‘2019-12-17‘),"%str(i+10001)

with open("b.txt", "a") as fp:

fp.write(a+"

")

执行完成后, b.text 文件的内容,需注意的是这里一定要改成 ;结尾,否则语法报错

部分数据内容展示如下

INSERT INTO apps.apiapp_card VALUES

(‘10001‘, ‘‘, ‘test123‘, ‘2019-12-17‘),

(‘10002‘, ‘‘, ‘test123‘, ‘2019-12-17‘),

......

(‘20000‘, ‘‘, ‘test123‘, ‘2019-12-17‘);

生成的 INSERT INTO 到 nicat 客户端执行

执行完成,看的测试结果,1w条数据只用了0.217秒,速度明显提高不少。

10w数据插入

接着测下,当生成10 w条数据的时候,会花多少时间?

作者:上海-悠悠 QQ群717225969

python3

insert_sql = "INSERT INTO apps.apiapp_card VALUES "

with open("b.txt", "a") as fp:

")

for i in range(100000):

a = "(‘%s‘, ‘‘, ‘test123‘, ‘2019-12-17‘),"%str(i+100000)

with open("b.txt", "a") as fp:

fp.write(a+"

")

使用python脚本执行后生成的数据如下

INSERT INTO apps.apiapp_card VALUES

(‘100000‘, ‘‘, ‘test123‘, ‘2019-12-17‘),

(‘100001‘, ‘‘, ‘test123‘, ‘2019-12-17‘),

......

(‘199999‘, ‘‘, ‘test123‘, ‘2019-12-17‘);

直接插入mysql 这时候会有报错:Err 1153 - Got a packet bigger than ‘max_allowed_packet‘ bytes

报错原因:由于数据量较大,mysql 会对单表数据量较大的 SQL 做限制,10w条数据的字符串超出了max_allowed_packet

的允许范围。

解决办法:需修改mysql 数据库的max_allowed_packet的值,改大一点

max_allowed_packet

先在 nicat 输入命令查看 max_allowed_packet 允许包

查看到 value 值是 4194304, 限制是 40 M,我们只需的sql字符串太大了,超出了这个范围。

在 nicat 客户端我们无法直接修改对应 value值,需登录到mysql,用命令行修改。

我这里 mysql 是搭建在 docker 上,需先进容器,登录到mysql.

作步骤如下:

docker exec 进docker容器

mysql -uroot -p 输入密码后登录mysql

set global max_allowed_packet=419430400; 设置允许包 400M

show global variables like ‘max_allowed_packet‘; 查看前面设置是否生效

[root@VM_0_2_centos ~]# docker exec -it 934b30a6dc36 /bin/bash

root@934b30a6dc36:/# mysql -uroot -p

Enter password:

Welcome to the MySQL monitor. Commands end with ; or g.

Your MySQL connection id is 303822

version: 5.7.27 MySQL Community (GPL)

Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its

affiliates. Other names may be trademarks of their respective

owners.

Type ‘;‘ or ‘h‘ for . Type ‘c‘ to clear the current input statement.

mysql> show global variables like ‘max_allowed_packet‘;

+--------------------+-----------+

| Variable_name | Value |

+--------------------+-----------+

| max_allowed_packet | 4194304 |

+--------------------+-----------+

1 row in set (0.00 sec)

mysql> set global max_allowed_packet=419430400;

Query OK, 0 rows affected (0.00 sec)

mysql> show global variables like ‘max_allowed_packet‘;

+--------------------+-----------+

| Variable_name | Value |

+--------------------+-----------+

| max_allowed_packet | 419430400 |

+--------------------+-----------+

1 row in set (0.00 sec)

mysql>

从上面的查询结果可以看到,已经生效了。

再次重新执行上面10w条数据,查看运行结果总共花11秒左右时间。

受影响的行: 100000

时间: 11.678s

上面的方法只能临时生效,当重启mysql后,你会发现又还原回去了。

这里还有一种生效的方法,需修改myf配置文件

在[mysqld]部分添加一句,如果有就修改对应的值:

max_allowed_packet=40M

3、网络问题这里的值,可以用 M单位,修改后,需要重启下mysql就可以生效了

使用python执行

如果不用 nicat 客户端,直接用python去执行,会花多少时间呢?

先封装连接mysql的方法,然后拼接执行的sql语句,拼接的时候需注意,的字符 ,需改成 ;

在执行代码前先获取当前的时间戳,代码执行完成后再次获取一次时间戳。两次的时间间隔,就是执行的时间了,时间单位是s

python 执行 mysql 代码参考如下

import pymysql

python3

作者:上海-悠悠 QQ群717225969

pip install PyMySQL==0.9.3

db = {

"host": "192.168.1.x",

"user": "root",

"password": "123456",

"port": 3306}

class DbConnect():

def init(self, db_cof, database=""):

self.db_cof = db_cof

# 打开数据库连接

cursorclass=pymysql.cursors.DictCursor,

db_cof)

# 使用cursor()方法获取作游标

self.cursor = self.db.cursor()

def select(self, sql):

# SQL 查询语句

# sql = "SELECT FROM EMPLOYEE # WHERE INCOME > %s" % (1000)

self.cursor.execute(sql)

results = self.cursor.fetchall()

return results

def execute(self, sql):

# SQL 删除、提交、修改语句

# sql = "DELETE FROM EMPLOYEE WHERE AGE > %s" % (20)

try:

# 执行SQL语句

self.cursor.execute(sql)

# 提交修改

self.dbmit()

except:

# 发生错误时回滚

self.db.rollback()

def close(self):

# 关闭连接

self.db.close()

if name == ‘main‘:

import time

insert_sql = "INSERT INTO apps.apiapp_card VALUES "

insert_values = "".join(["(‘%s‘, ‘‘, ‘test123‘, ‘2019-12-17‘),

"%str(i+100000) for i in range(100000)])

# 拼接sql

sql = insert_sql + insert_values[:-3]+";"

# print(sql)

# 执行sql

time1 = time.time()

db = DbConnect(db, database="apps")

db.execute(sql)

db.close()

time2 = time.time()

print("总过耗时:%s" % (time2-time1))

使用python执行结果:总过耗时:1.0816256999969482,结果超出我的想象,10w条数据居然只要1秒钟!

面试题:如何造10w条测试数据,在数据库插入10w条不同数据

标签:sql 语句提高names数据==commandatiblewhere

Ubuntu 16.04下Docker部署SpringBoot、Mysql、Redis、Nginx和Vue

本文以开源项目SpringBlade和Saber为例。

1、创建自定义网络

目的是将用到的服务都放到同一个网络段,以方便互相通信。

docker network create --subnet 172.19.0.0/16 mynetwork

2、Docker安装MySQL、Redis、Nginx

(1)安装MySQL

docker pull mysql:5.7.30

cd ~

mkdir docker/mysql/{conf,logs,data} -p

cd docker/mysql

docker run --name mysql_blade --network=mynetwork --ip=172.19.0.6 -p 3307:3306 -v PWD/logs:/var/log/mysql -v PWD/data:/data:rw -v $PWD/conf/redis.conf:/etc/redis/redis.conf:ro --privileged=true --name redis-6389 -d redis redis-server /etc/redis/redis.conf

(3)安装Nginx

将Saber发布到Nginx中要用到

docker pull nginx

2、Docker打包SpringBlade

3、Docker打包并发布Saber

(1)编写nginx.conf

cd Saber

touch nginx.conf,写入以下内容:

//nginx.conf开始

user root;

worker_processes 1;

error_log /var/log/nginx/error.log warn;

pid /var/run/nginx.pid;

nts {

worker_connections 1024;

} {

include /etc/nginx/mime.types;

default_type application/octet-stream;

}//nginx.conf结束

(2)修改env.js文件

baseUrl要与下面的SpringBlade容器的地址和端口匹配:

(3)编写Dockerfile

编写dockerfile并docker export -o pg_1018export.tar 63将其放到与dist同一目录:

FROM nginx

VOLUME /tmp

ENV LANG en_US.UTF-8

ADD ./dist/ /usr/share/nginx/html/

COPY./nginx.conf /etc/nginx/

EXPOSE 1889

EXPOSE 443

(4)打包并发布

cd ~

mkdir docker/saber/conf -p

cd docker/saber

cp ~/Saber/nginx.conf conf

yarn run build

docker build -t saber:1.0 .(注意的.)

docker run -itd --name saber --network=mynetwork --ip=172.19.0.8 -p 1889:1889 -v $PWD/conf:/mnt/ saber:1.0

4、Docker打包并发布SpringBlade

(1)pom.xml配置 / .xml

org.springframework.boot

spring-boot-men-plugin

{project.build.finalName}

repackage

com.spotify

dockerfile-men-plugin

{project.basedir}

{docker.registry.name}/ {docker.image.tag}

target/ {ja.version}

${ja.version}

UT另外,我通过uri来区分多租户。例如localhost:1889是管理租户,localhost:1889/test是名为test的租户。这样就避免了在登录界面填写租户id。F-8

-parameters

(2)yml配置

redis及mysql都要与前面的创建容器时的配置相同:

(3)创建私有仓库(利用Harbor)

在harbor管理界面创建项目blade,下面上传镜像的时候要加入项目路径。

(4)打包

mvn clean install dockerfile:build -Dmen.test.skip=true

两种方式:

mvn dockerfile:push

或者docker push 10.10.0.127:10080/blade/springblade:0.0.1

然后在Harbor管理后台就可以看到镜像了。

要pull下来的话:

docker pull 10.10.0.127:10080/blade/springblade:0.0.1

(6)发布

cd ~

mkdir docker/blade/app -p

cd docker/blade

docker run -itd --name blade --network=mynetwork --ip=172.19.0.7 -p 9001:9001 -v $PWD/app:/mnt/ 10.10.0.127:10080/blade/springblade:0.0.1

至此,就可以通过localhost:1889来访问Saber了。

怎么用通俗易懂的话来解释Docker(容器)技术

self.db = pymysql.connect开启远程连接(database=database,

“极简k8s入门”系列教程是一套帮助学习人员快速入门k8s的教程。“极简k8s入门”视频教程适合不熟悉容器编程的学习者学习。“极简k8s入门”帮助学习者快速上手,能够使用k8s进行部署及管理应用。

Docker系列二:玩转单个容器

那么对于宿主机上运行的服务比,在容器内运行有以下两种优势

1.配置:将服务放入容器,提前配置好提供服务所需的程序、库、配置文件等,无须担心宿主机是否有这些组件。若有需要也很容易将容器迁移到另一个宿主机上。

2.隔离:每个容器有自己单独的文件系统和网络接口,能按需运行多个相同的服务容器。每个容器使用各自的IP和端口来公开其服务,这些服务之间不会彼此冲突。

在虚拟机内安装容器测试后发现虚拟机内的容器性能接近于物理机。

1.查看容器镜像 docker ps -a

2.进入容器里面 docker exec -it f74716b965d7 /bin/bash 或者 docker exec -it f74716b965d7 "bash"

3.在容器内运行命令 apt-get update

如图所示可以安装想装的软件了 apt-get install vim

registry是一个位置——在那里能够找到许多reitory相关联的镜像。

reitory是一个名字——Docker用它来代表多个镜像。

docker search ubuntu

docker search -s 10 ubuntu

国内从 Docker Hub 拉取镜像有时会遇到困难,此时可以配置镜像加速器。Docker 和国内很多云服务商都提供了国内加速器服务,我们以 Docker 加速器 为例。

CentOS 7

请在 /etc/docker/daemon.json 中写入如下内容(如果文件不存在请新建该文件)

之后重新启动服务。

配置加速器之后,如果拉取镜像仍然十分缓慢,请手动检查加速器配置是否生效,在命令行执行 docker ,如果从结果中看到了如下内容,说明配置成功。

搜索想要的镜像

然后根据旁边的提示 docker pull oraclelinux

拉取镜像并不是将镜像放入系统的方式,可以将本地系统的镜像保存到一个tar文件,然后传输到另外一个系统中,在那里装载他。

docker se 命令会保存与特定的reitory关联所有的镜像。

查看docker下的镜像,选择mysql进行打包。

docker images

docker se -o mysql.tar mysql

du -sh mysql.tar

修改mysql权限,root注意要有

用SCP命令传输tar文件到另外一个系统中【centos传输至unbuntu】

【unbuntu需要scp能连接上】

sudo apt install

scp mysql.tar 192.168.140.134:/tmp

在unbuntu中装载mysql.tar

docker load -i /tmp/mysql.tar

docker import pg_1018export.tar pg3

但是需要注意运行导入的镜像的时候必须带command,否则容器不能运行。

在新的地这里我们拉取的版本的镜像:方装载

docker se保存的是镜像(image),docker export保存的是容器(container)

查看镜像,进行打包

查看容器,进行打包

对比两者打包后的大fp.write(insert_sql+"小和内容

对比可以看到容器内容是一个linux的文件目录

镜像的内容拆开看到:

其实就是一个分层的系统

Docker镜像实际上就是由这样的一层层文件进行叠加起来的,上层的文件会覆盖下层的同名文件。

如果将镜像中各层文件合并到一起,基本就是容器打包后内容。由于镜像里的各层文件会有很多重复文件,所以镜像打包后会比容器大那么一点。

se — 镜像 打包—用 load 载入,用import可以载入但启动不了。

export — 容器 打包—用 import 载入,用load不能载入,docker load必须要载入的是一个分层文件系统。

查看正在运行或暂停容器 docker ps

查看停止的容器 docker ps -a

启动 docker start CONTAINER ID

停止 docker stop CONTAINER ID

重启 docker restart CONTAINER ID

暂停 docker pause CONTAINER ID

取消暂停 docker unpause CONTAINER ID

docker run 创建新的容器

语法

docker run [OPTIONS] IMAGE [COMMAND] [ARG...]

详细见

以mysql的镜像为例子

[root@localhost text]# docker run -it mysql /bin/bash

然后也可以达到进入容器内的相同效果

开发者可以使用Docker做什么?

在Ubuntu系统中安装较为简单,提供了脚本供我们进行安装。

【编者的话】有些开发者可能还是不明白 Docker 对自己到底有多大的用处,因此翻译 Docker 个人用例 这篇文章中来介绍 Docker 在普通开发者开发过程中的用例。

Docker 如今赢得了许多关注,很多人觉得盛名之下其实难副,因为他们仍然搞不清 Docker 和普通开发者到底有什么关系。许多开发者觉得 Docker 离自己很远,Docker 是生产环境中的工具,和自己无关。我也是花了很长时间才想清楚作为普通开发人员如何在自己的开发中使用 Docker。坦率地说,我仍处在学习的过程中。

这篇文章提供了一个 Docker 用例列表,我希望它能更好地帮助你理解 Docker 并引发你的思考。本文只是show global variables like ‘max_allowed_packet‘;描述 Docker 在普通开发者日常的应用,并不提供完整的解决方案。

在介绍用例之前,我希望你能先记住这句话:“Docker 是一个便携的应用容器”。你可以不知道 Docker 所说的的“便携式容器”到底是什么意思,但是你必须清楚 Docker 在日常中能带来非常大的效率提升。

当你需要在容器内运行自己的应用(当然可以是任何应用),Docker 都提供了一个基础系统镜像作为运行应用时的基础系统。也就是说,只要是 Linux 系统上的应用都可以运行在 Docker 中。

可以在 Docker 里面运行数据库吗?当然可以。

可以在 Docker 里面运行 Node.js 网站吗?当然可以。

可以在 Docker 里面运行 API 吗?当然可以。

Docker 并不在乎你的应用程序是什么、做什么,Docker 提供了一组应用打包、传输和部署的方法,以便你能更好地在容器内运行任何应用。

下面的例子我自己经常使用,当然你有更好的案例也可以分享给我。

尝试新软件

对开发者而言,每天会催生出的各式各样的新技术都需要尝试,然而开发者却不太可能为他们一一搭建好环境并进行测试。时间非常宝贵,正是得益于 Docker,让我们有可能在一条或者几条命令内就搭建完环境。Docker 有一个傻瓜化的获取软件的方法,Docker 后台会自动获得环境镜像并且运行环境。

并不仅仅是新技术环境搭建用得到 Docker。如果你想快速在你的笔记本上运行一个 MySQL 数据库,或者一个 Redis 消息队列,那么使用 Docker 便可以非常容易地做到。例如 Docker 只需要一条命令便可以运行 MySQL 数据库:docker run -d -p 3306:3306 tutum/mysql。

译者注:虽然使用命令也能非常快地安装 MySQL 数据库,但是当用到的技术或者非常复杂的技术时,使用 Docker 便会是个非常好的选择,例如 Gitlab,普通用户大概需要一天的时间去搭建 Gitlab 平台,而 Docker 则只需要一条命令。

进行演示

现在我经常需要在周末用自己开发的成果对客户活着别人做一两个演示。搭建演示环境的过程非常麻烦。现在我发现 Docker 已经成为我演示这些工具的最合理的方式。同时,对于客户来说,我可以直接将 Docker 镜像提供给他们,而不必去做任何环境配置的工作,工作的效果也会和在他们演示中所看到的一模一样,同时不必担心他们的环境配置会导致我们的产品无法运行。

避免“我机器上可以运行”

无论是上一篇介绍的企业部署 Docker 还是本文的个人 Docker 用例,都提到了这个情况。因为环境配置不同,很多人在开发中也会遇到这个情况,甚至开发的软件到了测试人员的机器上便不能运行。但这都不是重点。重点是,如果我们有一个可靠的、可分发的标准开发环境,那么我们的开发将不会像现在这么痛苦。Docker 便可以解决这个问题。Docker 镜像并不会因为环境的变化而不能运行,也不会在不同的电脑上有不同的运行结果。可以给测试人员提交含有应用的 Docker 镜像,这样便不再会发生“在我机器上是可以运行的”这种事情,很大程度上减轻了开发人员测试人员互相检查机器环境设置带来的时间成本。

另一个 Docker 可以发挥用处的地方是培训班。除了 Docker 容器的隔离性之外,更能体会到 Docker 优势的地方在于环境搭建。培训班的新手每个人都要在环境搭建上花费很多时间,但是如果在这里应用到 Docker 的话,那么我们只需要把标准的运行环境镜像分发下去,然后就可以开始上课了。使用 Docker 和使用虚拟机一样简单,但是 Docker 要更方便、更轻量级。同时,我们也可以告诉学员:“在培训的同时,我们还将学到当下的技术——Docker”,这种双赢的结局,何乐而不为呢。

学习 Linux 脚本

当然这个原因看起来可能很奇怪,但是对不不熟悉 Linux 作系统和 Shell 脚本的人来说,确实是一个好机会。即便本文并不是在讲 Linux,Linux 的重要度仍然不言而喻。如果你用的是 Windows,那么我给你一个建议:从云主机提供商那儿租用一台云主机:我使用 CoreOS 系统的云主机。虽然这样并不会让你成为专业的 Linux 运维,但是可以让你快速地学到 Linux 基础知识,爱上命令行作,并且慢慢开始熟悉和欣赏 Linux。

更好地利用资源

虚拟机的粒度是“虚拟出的机器”,而 Docker 的粒度则是“被限制的应用”,相比较而言 Docker 的内存占用更少,更加轻量级。

对我来说这是 Docker 的一个优势:因为我经常在自己电脑中运行多个 Docker 应用,使用 Docker 比使用虚拟机更加简单,方便,粒度更细,也能持续地跟踪容器状态。

为微服务定制

如果你一直在关注科技的话,那么你应该听说过“微服务(Microservs)”的概念。Docker 可以很好地和微服务结合起来。从概念上来说,一个微服务便是一个提供一整套应用程序的部分功能,Docker 便可以在开发、测试和部署过程中一直充当微服务的容器。甚至生产环境也可以在 Docker 中部署微服务。

在云服务提供商之间移植

大多数的云主机提供商已经全面支持 Docker。对于开发人员来说,这表示你可以很方便地切换云服务提供商,当然也可以很方便地将你本地的开发环境移动到云主机上,不需要本地上配置一次运行环境、在云主机上还配置一次运行环境。全面部署 Docker (Docker here and Docker there) 作为标准运行环境可以极大地减轻应用上线时的工作量和产生 BUG。

我们是否应该将数据库也容器化?

INSERT INTO apps.apiapp_card (id, card_id, card_user, add_time) VALUES (‘1860000000‘, ‘‘, ‘test123‘, ‘2019-12-17‘);

Docker不适合部署数据库的7大原因

针对上面问题是不是说数据库一定不要部署在容器里吗?

1、数据安全问题

不要将数据储存在容器中,这也是 Docker 容器使用技巧中的一条。容器随时可以停止、或者删除。当容器被rm掉,容器里的数据将会丢失。为了避免数据丢失,用户可以使用数据卷挂载来存储数据。但是容器的 Volumes 设计是围绕 Union FS 镜像层提供持久存储,数据安全缺乏保证。如果容器突然崩溃,数据库未正常关闭,可能会损坏数据。另外,容器里共享数据卷组,对物理机硬件损伤也比较大。

使用当前的存储驱动程序,Docker 仍然存在不可靠的风险。如果容器崩溃并数据库未正确关闭,则可能会损坏数据。

2、性能问题

大家都知道,MySQL 属于关系型数据库,对IO要求较高。当一台物理机跑多个时,IO就会累加,导致IO瓶颈,大大降低 MySQL 的读写性能。

在一次Docker应用的十大难点专场上,某国有银行的一位架构师也曾提出过:“数据库的性能瓶颈一般出现在IO上面,如果按 Docker 的思路,那么多个docker最终IO请求又会出现在存储上面。现在互联网的数据库多是share nothing的架构,可能这也是不考虑迁移到 Docker 的一个因素吧”。

针对性能问题有些同学可能也有相对应的方案来解决:

(1)数据库程序与数据分离

如果使用Docker 跑 MySQL,数据库程序与数据需要进行分离,将数据存放到共享存储,程序放到容器里。如果容器有异常或 MySQL 服务异常,自动启动一个全新的容器。另外,建议不要把数据存放到宿主机里,宿主机和容器共享卷组,对宿主机损坏的影响比较大。

(2)跑轻量级或分布式数据库

Docker 里部署轻量级或分布式数据库,Docker 本身就服务挂掉,自动启动新容器,而不是继续重启容器服务。

(3)合理布局应用

对于IO要求比较高的应用或者服务,将数据库部署在物理机或者KVM中比较合适。目前TX云的TDSQL和阿里的Oceanbase都是直接部署在物理机器,而非Docker 。

要理解 Docker 网络,您必须对网络虚拟化有深入的了解。也必须准备应付好意外情况。你可能需要在没有支持或没有额外工具的情况下,进行 bug 修复。

我们知道:数据库需要专用的和持久的吞吐量,以实现更高的负载。我们还知道容器是虚拟机管理程序和主机虚拟机背后的一个隔离层。然而网络对于数据库是至关重要的,其中需要主从数据库间 24/7 的稳定连接。未解决的 Docker 网络问题在1.9版本依然没有得到解决。

把这些问题放在一起,容器化使数据库容器很难管理。我知道你是一个的工程师,什么问题都可以得到解决。但是,你需要花多少时间解决 Docker 网络问题?将数据库放在专用环境不会更好吗?节省时间来专注于真正重要的业务目标。

4、状态

在 Docker 中打包无状态服务是很酷的,可以实现编排容器并解决单点故障问题。但是数据库呢?将数据库放在同一个环境中,它将会是有状态的,并使系统故障的范围更大。下次您的应用程序实例或应用程序崩溃,可能会影响数据库。

知识点:在 Docker 中水平伸缩只能用于无状态计算服务,而不是数据库。

Docker 快速扩展的一个重要特征就是无状态,具有数据状态的都不适合直接放在 Docker 里面,如果 Docker 中安装数据库,存储服务需要单独提供。

目前,TX云的TDSQL(金融分布式数据库)和阿里云的Oceanbase(分布式数据库系统)都直接运行中在物理机器上,并非使用便于管理的 Docker 上。

5、资源隔离

资源隔离方面,Docker 确实不如虚拟机KVM,Docker是利用Cgroup实现资源限制的,只能限制资源消耗的值,而不能隔绝其他程序占用自己的资源。如果其他应用过渡占用物理机资源,将会影响容器里 MySQL 的读写效率。

我们没有看到任何针对数据库的隔离功能,那为什么我们应该把它放在容器中呢?

6、云平台的不适用性

大部分人通过共有云开始项目。云简化了虚拟机作和替换的复杂性,因此不需要在夜间或周末没有人工作时间来测试新的硬件环境。当我们可以迅速启动一个实例的时候,为什么我们需要担心这个实例运行的环境?

这就是为什么我们向云提供商支付很多费用的原因。当我们为实例放置数据库容器时,上面说的这些便利性就不存在了。因为数据不匹配,新实例不会与现有的实例兼容,如果要限制实例使用单机服务,应该让 DB 使用非容器化环境,我们仅仅需要为计算服务层保留弹性扩展的能力。

7、运行数据库的环境需求

常看到 DBMS 容器和其他服务运行在同一主机上。然而这些服务对硬件要求是非常不同的。

数据库(特别是关系型数据库)对 IO 的要求较高。一般数据库引擎为了避免并发资源竞争而使用专用环境。如果将你的数据库放在容器中,那么将浪费你的项目的资源。因为你需要为该实例配置大量额外的资源。在公有云,当你需要 34G 内存时,你启动的实例却必须开 64G 内存。在实践中,这些资源并未完全使用。

怎么解决?您可以分层设计,并使用固定资源来启动不同层次的多个实例。水平伸缩总是比垂直伸缩更好。

总结

是:并不是

我们可以把数据丢失不敏感的业务(搜索、埋点)就可以数据化,利用数据库分片来来增加实例数,从而增加吞吐量。

docker适合跑轻量级或分布式数据库,当docker服务挂掉,会自动启动新容器,而不是继续重启容器服务。

数据库利用中间件和容器化系统能够自动伸缩、容灾、切换、自带多个,也是可以进行容器化的。

见仁见智,一般不用容器做状态或持久化的东西,因为无法保证数据安全。当然,你如果是类似于一主多从,并对数据一致性没有的要求,那用容器跑几个只读从库也没啥不可以

applem2不支持dockermysql5.7

需要的隔离级别越多,获得的资源开销就越多。相比专用环境而言,容易水平伸缩是Docker的一大优势。然而在 Docker 中水平伸缩只能用于无状态计算服务,数据库并不适用。

您要问的是applem2不支持dockermysql5.7的原因是什么?原因如下:

1、Docker上的MySQL5.7是为基于x86架构的计算机设计的,而AppleM1芯片使用的是基于ARM架构的处理器。这意味着Docker容器中的MySQL5.7二进制文件无法在M1芯片上运行,因为它们是不同的架构。

2、MySQL5.7是为x86架构编译的,因此其中的某些部分会依赖于x86特定的指令集或库,而这些指令集和库在ARM架构上会不可用或者性能较。

Ubuntu Docker 安装和使用

for i in range(10000):

Docker 划分为CE 和EE。CE 即社区版(免费,支持周期三个月),EE 即企业版,强调安全,付费使用。

执行这个命令后,脚本就会自动的将一切准备工作做好,并且把Docker CE 的Edge版本安装在系统中。

启动Docker CE

建立docker 用户组

默认情况下,docker 命令会使用Unix socket 与Docker 引擎通讯。而只有root 用户和docker 组的用户才可以访问Docker 引擎的Unix socket。出于安全考虑,一般Ubuntu系统上不会直接使用root 用户。因此,更好地做法是将需要使用docker 的用户加入docker用户组。

注销当前用户,重新登录Ubuntu,输入docker ,此时可以直接出现信息。

配置国内镜像加速

在/etc/docker/daemon.json 中写入如下内容(如果文件不存在请新建该文件)

重新启动服务

测试

我们通过 docker 的两个参数 -i -t,让 docker 运行的容器实现"对话"的能力:

各个参数解析:

-t: 在新容器内指定一个伪终端或终端。

-i: 允许你对容器内的标准输入 (STDIN) 进行交互。

我们可以通过运行 exit 命令或者使用 CTRL+D 来退出容器。

使用以下命令创建一个以进程方式运行的容器

二、使(5)上传到私有仓库用Docker安装 MySQL

用 docker search mysql 命令来查看可用版本:

2、拉取 MySQL 镜像

3、查看本地镜像

使用以下命令来查看是否已安装了 mysql:

4、运行容器

安装完成后,我们可以使用以下命令来运行 mysql 容器:

大小写敏感

参数说明:

-p 3306:3306 :映射容器服务的 3306 端口到宿主机的 3306 端口,外部主机可以直接通过 宿主机ip:3306 访问到 MySQL 的服务。

MYSQL_ROOT_PASSWORD=123456:设置 MySQL 服务 root 用户的密码。

使用docker exec进入Docker容器

从容器里面拷文件到宿主机

docker cp mysql-5.7:/etc/mysql/ /home

从宿主机拷文件到容器里面

docker cp /home/s/myf mysql-5.7:/etc/mysql/

大小写敏感修改

/etc/myf 中的[mysqld]后添加添加lower_case_table_names=1,重启MYSQL服务 0敏感 1不敏感

5、安装成功

通过 docker ps 命令查看是否安装成功:

6、连接

mysql -oot -P3308 -h 127.0.0.1 -p