• Jmeter常用函数之__CSVRead使用
    __CSVRead函数用于对脚本进行参数话,当脚本中不同变量需要不同参数值时,可以考虑__CSVRead函数。 以登录的用户名、密码为例:实际进行压力测试时,需要模拟使用不同的用户并发访问系统,此时需要我们对脚本中的用户名、密码进行参数化;下面具体介绍如何使用csvread函数: 1. 准备好参数取值List清单,文件格式为:csv或者txt文件,里面保存变量要读取的参数值,每个变量间用逗号相隔。每行表示每一组参数值,每列表示同一种变量; 如准备10个不同的用户,文件名user parameter.txt,其用户名、密码取值如下: liuke01@163.com,12 liuke02@163.com,123 liuke03@163.com,hai123 liuke04@163.com,12abc liuke05@163.com,23dcs liuke06@163.com,ed12q liuke07@163.com,jumper liuke08@163.com,poi2qwe liuke09@163.com,122dewq  liuke10@163.com,123dew23 2.准备好参数取值List清单后,打开Jmeter的函数助手,选择csvread函数,生成函数; 在Jmeter“选项”中-->选择“函数助手对话框”-->选择csvread函数或者直接采用快捷键Ctrl+F打开, 其中:   CSV file to get values from | *alias:表示要读取的文件路径,应该是绝对路径(如:D:\Software\jmeter\User parameter.txt)   CSV文件列号| next| *alias:表示当前变量读取第几列数据,注意第一列是0   点击生成按钮,则生成了函数,如:${__CSVRead(D:\jmeter\User parameter.txt,0)},表示是从D:\jmeter\User parameter.txt文件中第一列读取数据。以此类推。 3.在Jmeter录制的脚本中,找到登录这块需要参数桦的用户名、密码,对用户名、密码的value值进行参数化,其中用户名的value值替换为${__CSVRead(D:\jmeter\User parameter.txt,0)},密码的value值替换为${__CSVRead(D:\jmeter\User parameter.txt,1)},保存当前脚本,参数化完毕,(注:如果要修改要读取的参数值,则可直接在txt清单中修改数字而不用重新在csvread函数生成中修改)4.Jmeter执行的时候,如果有多个线程,顺序读取第一行的数字,如果线程组多于文件中的行数,则循环读取。
  • [实践系列] GaussDB(DWS)实践系列—关于释放磁盘异常占用空间的经验总结
    【摘要】 集群在运行过程中,可能会出现部分节点目录的磁盘使用率偏高,并且仍在不断增长的情况,如果不及时处理可能会因为磁盘使用率超限而影响集群正常运行。例如使用df –h查看到某个目录的磁盘使用率达到70%,远高于集群内的其他节点,但是使用du –sh命令查看对应目录并未发现异常占用磁盘空间的大文件。针对上述情况,就需要排查可能是哪个进程占用了已经被删除了的文件句柄,导致磁盘空间并未真正释放。本文档主要介绍如GaussDB(DWS)运维的那些事?——关于释放磁盘异常占用空间的经验总结一、   摘要        集群在运行过程中,可能会出现部分节点目录的磁盘使用率偏高,并且仍在不断增长的情况,如果不及时处理可能会因为磁盘使用率超限而影响集群正常运行。例如使用df –h查看到某个目录的磁盘使用率达到70%,远高于集群内的其他节点,但是使用du –sh命令查看对应目录并未发现异常占用磁盘空间的大文件。针对上述情况,就需要排查可能是哪个进程占用了已经被删除了的文件句柄,导致磁盘空间并未真正释放。本文档主要介绍如何通过清理残留进程,释放被异常占用的磁盘空间。二、   原因说明(一)   Linux异常占用磁盘空间情况说明        在Linux操作系统中,当一个文件被删除后,在文件系统目录中已经不可见了,所以du就不会再统计它了。然而如果此时还有运行的进程持有这个已经被删除了的文件的句柄,那么这个文件就不会真正在磁盘中被删除,分区超级块中的信息也就不会更改,所以df 命令查看磁盘占用没有减少。本文主要通过排查清理此类的残留进程,释放磁盘空间。(二)   lsof命令说明        lsof是linux下用于查看打开的文件以及相关关联进程信息的工具,执行lsof,将输出系统中打开文件的信息,包括与文件关联的进程的名字、进程pid、用户、目录、socket套接字、和命名管道等。使用该工具来查找残留进程。三、   操作实践        在巡检时发现节点10.77.20.XXX的根目录‘/’磁盘使用率达到 49%,明显高于其他节点,使用 du -sh * 命令查看该目录文件,未发现有大文件占用磁盘空间。考虑到可能存在未知进程占用文件句柄,导致磁盘空间异常。需要运用lsof工具查看相关关联进程占用已经删除的文件句柄信息。使用命令lsof | grep deleted 命令获取已经被删除但是仍然被应用程序占用的文件列表。考虑到文件列表行数过多,包含其他目录文件信息,不便于筛选定位,将其导入到文件中进行查找。参考命令:lsof | grep deleted > deleted_info.log过滤其他目录信息参考命令:cat deleted_info.log | grep -v "/srv/BigData/mppdb "  > new2.log最终定位到一个残留的bash 进程,占用文件句柄,且该目录下无法找到该文件。判断是此进程占用了文件句柄,导致磁盘异常占用,应及时清理该残留进程。清理定位到的残留进程参考命令:kill -9 53249  (对应进程的pid)使用df -h命令再次查看磁盘空间,‘/’目录磁盘空间使用率从49%降为18%:四、   总结延伸  从释放异常占用磁盘空间的操作过程分析,由于前期运维人员在删除过期文件时忽略了该文件是被进程占用的情况,删除了文件却没有重启或清除进程所导致的。因此在linux系统中删除累积性文件时可以使用lsof命令查看一下文件是否有被进程占用,在删除文件后可以重启或清除相关进程,避免产生磁盘空间异常占用,为日后维护带来不便。
  • [技术干货] Freeradus常见问题及解决方法
    安装完成后提示某文件找不到解决方法:使用命令 ldconfig    作用:让动态链接库为系统所共享开启服务时显示无法写入日志文件解决方法:使用命令 chmod    作用:添加用户权限例如:chmod 777 radius                chmod +x radius.log开启服务时显示端口被占用,例如  error-binding to port for 0.0.0.0 port 1812解决方法:使用命令 lsof –i:1812检查1812端口被哪个进程占用,使用kill [PID] 杀死相应进程认证可以通过,但是计费失败expand: /usr/local/var/log/radius/radacct/%{Client-IP-Address}/detail-%Y%m%d -> /usr/local/var/log/radius/radacct/10.137.230.118/detail-20120310rlm_detail: /usr/local/var/log/radius/radacct/%{Client-IP-Address}/detail-%Y%m%d expands to /usr/local/var/log/radius/radacct/10.137.230.118/detail-20120310rlm_detail: Failed to create directory /usr/local/var/log/radius/radacct/10.137.230.118: Permission denied显示原因为添加计费日志失败,对计费文件夹添加权限:linux:/usr/local/var/log/radius # chmod 777 radacct/linux:/usr/local/var/log/radius # chmod +x radacct/
  • [其他] 【重分布】数据重分布重入时delete pgxc_redistb操作耗时长,3小时以上无法完成
    发生版本【GaussDB(DWS)】【C80SPC600】问题描述将重分布进程杀掉重入,长时间不能进入表重分布阶段,后台查看第一个cn上PG_STAT_ACTIVITY视图,发现是在执行如下语句:delete from pgxc_redistb where(nspname, relname) not in ( select n.nspname, c.relname from pg_class c,pg_namespace n where c.relnamespace = n.nspname);问题分析重分布重入时需要先将pgxc_redistb中已完成重分布的表记录剔除掉,此剔除语句执行慢。解决方案1、首先停止重分布进程;2、查看当前事务,cancel掉redis进程调起的语句   select pg_cancel_backend(pid)  from pg_stat_activity where application_name = 'gs_redis' and query like 'DELETE FROM pgxc_redistb%';3、修复表字段,在每个数据库下执行语句:set enable_cluster_resize = on;alter table pgxc_redistb alter column relname set not null;alter table pgxc_redistb alter column nspname set not null;4、重新调起重分布命令。
  • [交流分享] linux pidof 查看指定服务进程的pid值
    ### ECS信息 * 规格:通用入门型 | t6.large.1 | 2vCPUs | 2GB * 镜像:openEuler 20.03 64bit | 公共镜像   ### linux pidof 查看指定服务进程的pid值 ``` bash $ pidof sshd 507876 507874 507873 507854 505477 505452 3524 ``` ``` bash $ ps aux | grep sshd root 3524 0.0 0.4 13448 7268 ? Ss Mar16 0:00 /usr/sbin/sshd -D root 505452 0.0 0.5 15100 8584 ? Ss 17:16 0:00 sshd: root [priv] root 505477 0.0 0.3 15100 5156 ? S 17:16 0:00 sshd: root root 507854 0.0 0.5 15100 8404 ? Ss 17:57 0:00 sshd: vhjwYUS [priv] vhjwYUS 507873 0.0 0.3 15100 4992 ? S 17:58 0:00 sshd: vhjwYUS root 507874 0.0 0.5 15096 9008 ? Ss 17:58 0:00 sshd: vhjwYUS [priv] vhjwYUS 507876 0.0 0.3 15096 4972 ? S 17:58 0:00 sshd: vhjwYUS@pts/0 vhjwYUS 509061 0.0 0.0 213308 900 pts/0 S+ 18:18 0:00 grep --color=auto sshd ```   ### 帮助文档(部分) ``` bash $ pidof --help Usage: pidof [options] [program [...]] Options: -s, --single-shot return one PID only -c, --check-root omit processes with different root -x also find shells running the named scripts -o, --omit-pid omit processes with PID -S, --separator SEP use SEP as separator put between PIDs -h, --help display this help and exit -V, --version output version information and exit For more details see pidof(1). ```   ### 学习资料 * openEuler-官网 openeuler.org/zh * openEuler-B站 space.bilibili.com/527064077 * openEuler-慕课 openeuler.org/zh/learn/mooc * openEuler-文档 openeuler.org/zh/documentation   欢迎各位同学来讨论~!
  • [交流分享] linux ps 查看系统中的进程状态
    ### ECS信息 * 规格:通用入门型 | t6.large.1 | 2vCPUs | 2GB * 镜像:openEuler 20.03 64bit | 公共镜像   ### linux ps 查看系统中的进程状态 #### BSD的格式 ps aux ``` bash $ ps aux USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND root 1 0.0 0.7 106296 11532 ? Ss 2313 0:06 /usr/lib/systemd/systemd --switched-root --syst root 2 0.0 0.0 0 0 ? S 2313 0:00 [kthreadd] root 3 0.0 0.0 0 0 ? I 2313 0:00 [rcu_gp] root 4 0.0 0.0 0 0 ? I 2313 0:00 [rcu_par_gp] root 6 0.0 0.0 0 0 ? I 2313 0:00 [kworker/0:0H-kblockd] root 7 0.0 0.0 0 0 ? I 2313 0:02 [kworker/u4:0-events_unbound] ``` #### BSD的格式+树形结构展示 ps auxf ``` bash $ ps auxf ...... USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND root 2 0.0 0.0 0 0 ? S 2313 0:00 [kthreadd] root 47 0.0 0.0 0 0 ? S Mar16 0:00 \_ [kswapd0] root 98 0.0 0.0 0 0 ? I Mar16 0:00 \_ [kthrotld] root 99 0.0 0.0 0 0 ? I Mar16 0:00 \_ [acpi_thermal_pm] ...... ```   #### 标准格式 ps -ef ``` bash $ ps -ef UID PID PPID C STIME TTY TIME CMD root 1 0 0 2313 ? 00:00:06 /usr/lib/systemd/systemd --switched-root --system --deserializ root 2 0 0 2313 ? 00:00:00 [kthreadd] root 3 2 0 2313 ? 00:00:00 [rcu_gp] root 4 2 0 2313 ? 00:00:00 [rcu_par_gp] ```   ### 帮助文档(部分) ``` bash # ps --help Usage: ps [options] Try 'ps --help ' or 'ps --help ' for additional help text. For more details see ps(1). ``` ``` bash # ps --help a Usage: ps [options] Basic options: -A, -e all processes -a all with tty, except session leaders a all with tty, including other users -d all except session leaders -N, --deselect negate selection r only running processes T all processes on this terminal x processes without controlling ttys Selection by list: -C command name -G, --Group real group id or name -g, --group session or effective group name -p, p, --pid process id ...... ```   ### 参考资料 * https://blog.csdn.net/a12345555555/article/details/72770789 * https://blog.csdn.net/ruibin_cao/article/details/84660224   ### 学习资料 * openEuler-官网 openeuler.org/zh * openEuler-B站 space.bilibili.com/527064077 * openEuler-慕课 openeuler.org/zh/learn/mooc * openEuler-文档 openeuler.org/zh/documentation   欢迎各位同学来讨论~!
  • [存储] 非侵入式备份及其在NBU上的应用
    1. 通用的备份方案介绍除Netbackup深度定制的厂商外,通常数据库厂商都按XBSA接口来实现NBU备份。首先在集群内每个节点安装NBU客户端,通过XBSA发命令至本地NBU客户端,然后NBU客户端与远端服务器上的NBU服务端程序通信,将数据写入挂载于远端的磁带或磁盘设备。早期的GaussDB(DWS)便是采用如此方式,应用于线下场景。下图展示了这个备份架构原理。如上图,GaussDB的备份工具Roach,在每个节点都启动一至多个Roach agent进程,用于读取本节点的GaussDB数据,并将其存入缓存buffer。然后调用XBSA接口,将缓存数据转发给NBU处理。不难看出,该架构的特点就是Netbackup第三方软件需要侵入式部署到我们的集群内,备份进程也要使用安装NBU Client时一起提供的libxbsa64.so动态库才能使用XBSA接口。这样就隐含了一个前提:Netbackup软件必须要有该集群所支持的OS的安装包。但是,云上环境基本都是欧拉OS,或者鲲鹏服务器,目前针对这些系统并没有Netbackup软件的安装包,这个前提变得不可获得。更进一步,适配更多第三方厂商的备份协议时,当前架构就要求第三方厂商必须支持欧拉OS、鲲鹏等版本,增加了各种组合的复杂性,不利于生态拓展。于是一种新的非侵入式备份架构呼之欲出。2. 非侵入式备份架构介绍非侵入式架构下,第三方厂商的客户端软件不部署在GaussDB集群内。同时,GaussDB开发一个新插件,部署于远端备份服务器上,负责与集群内的Roach工具进行通信,于是架构变为下图所示:这里说的新插件就是Roach client组件,用户使用前需要提前在备份服务器上部署该组件。和Roach工具一样,该组件也不允许以root用户部署,应当新建一个普通用户,在该用户下部署。图中NBU只是一种示例,其它第三方软件对接时原理也是相同的。展开一点来说,集群内每个节点都有Roach agent进程负责本节点一至多个DN实例的数据备份,该进程会根据DN个数fork出多个子进程,每个Roach agent子进程负责一个DN。备份出来的数据会转发给远端备份服务器的Roach client进程,该进程内部又会根据DN个数fork出多个子进程,每个子进程负责与一个DN(亦对应一个Roach agent)通信。这里不能创建为线程是因为XBSA本身限制,每个进程才能独占一份NBU链接。即有如下映射关系图:从性能角度考虑,需要根据一定比例配备多个NBU media server服务器。比如GaussDB集群有200个节点,每4个DN对应一个备份盘或磁带,每10个GaussDB节点配备一台NBU media server,则共需20台media服务器。示意图如下:3. 云上非侵入式NBU备份的使用用户可通过DWS管控面发起NBU备份操作,发起之前需按照非侵入式方式提前部署好NBU环境和Roach client组件。首先,可在插件下载界面提前down下来Roach client组件包(OS版本需要与NBU media server的系统相同):然后配置快照策略,图中的备份服务器即是NBU media server。接下来就可以创建快照了:创建快照成功后,后期即可使用该快照来恢复集群。原文链接:https://bbs.huaweicloud.com/blogs/245772【推荐阅读】【最新活动汇总】DWS活动火热进行中,互动好礼送不停(持续更新中)  HOT  【博文汇总】GaussDB(DWS)博文汇总1,欢迎大家交流探讨~(持续更新中)【维护宝典汇总】GaussDB(DWS)维护宝典汇总贴1,欢迎大家交流探讨(持续更新中)【项目实践汇总】GaussDB(DWS)项目实践汇总贴,欢迎大家交流探讨(持续更新中)【DevRun直播汇总】GaussDB(DWS)黑科技直播汇总,欢迎大家交流学习(持续更新中)【培训视频汇总】GaussDB(DWS) 培训视频汇总,欢迎大家交流学习(持续更新中)扫码关注我哦,我在这里↓↓↓
  • [存储] 华为云数仓GaussDB(DWS)全量备份总结
    数据备份恢复是保护数据安全的重要手段之一。Roach工具支持多种备份恢复类型,例如集群级的物理备份,表级备份的逻辑备份;分别支持DISK/NBU/OBS/EISOO几种备份介质;支持双集群间的容灾方案等,从而提供数据的可靠性保障机制。Roach支持如下功能:序号功能1物理备份恢复:全量备份、增量备份2逻辑备份恢复:单表、多表3物理备份集恢复到新集群4备份相关辅助功能:删除/校验/查看备份集、取消备份集5支持的存储介质:本地DISK、远端NAS/NBU/OBS/EISOO6支持的调度方式:命令行、FI、DWS管控面、EISOO界面(仅部分)7支持的集群形态:主备从、一主多备、小型化8双集群容灾:同构、异构(仅DISK)9双集群迁移:离线迁移10断点续做、NBU非侵入式部署等特性(仅部分介质)      本文将梳理Roach全量恢复的整体流程,描述Roach集群全量备份场景的运转机制,PITR、增量备份、断点续做、双集群、表级备份等功能不做阐述。一、简介       Roach的集群级备份采用的是物理备份,即通过物理文件拷贝的方式对数据库进行备份,通过备份的数据文件及日志等文件,数据库可以进行完全恢复。全量备份则是将当前时间点数据库中所有的数据进行备份。当然,全备份可以备份整块硬盘、整个分区或某个具体的目录。全备份的好处是数据恢复方便,因为所有的数据都在同一个备份中,所以只要恢复全备份,所有的数据都会被恢复。其优点是:物理备份速度快,通过合理规划,可以低成本进行备份和恢复;其缺点是:相较于增量备份备份时间较长。二、备份架构2.1 roach备份全局流程图       Roach备份采用生产者-消费者模式,下图展现了备份流程各个线程及IO交互图。exec线程作为生产者,同时为减轻exec线程的压力,增加并行的reader线程读取小文件;sender线程作为消费者;中间则是通过一个256MB(可设置)的大buffer衔接。      GaussDB内核的备份组件为GaussRoach.py和gs_roach,需在集群内拉起备份任务。2.2 调度流程GaussRoach.py:Roach单集群全量备份入口为GaussRoach.py。每次命令行输入“python GaussRoach.py –t backup…”后,roach的python语言模式就开始运行了。      任意节点均可作为主节点拉起GaussRoach.py,然后每个节点都启动gs_roach进程负责本节点备份,各节点并行备份,节点内各DN并行备份。2.3 备份具体流程2.4 接口调用       完成数据备份压缩后,需要将压缩文件传送到远端存储介质,实现存储介质与Roach备份流程松耦合,第三方介质不用关注Roach的备份流程,只需要按照接口实现即可完成与Roach的对接。同时Roach流程实现也不必关注底层存储介质实现,减少了不必要的分支判断。2.5 全量备份的内容根据Gauss数据库的功能结构,全量备份按照以下顺序备份所需要的文件:数据库相关的配置文件。行存全部数据:GaussDB A数据库支持行存。xlog日志文件:Roach支持在线业务的备份,则通过备份xlog日志文件可在恢复时将备份期间的业务Redo,保证数据一致性。列存全部数据: GaussDB A数据库支持列存。备份的数据按照每个节点为单位进行备份,所以每个节点都只存储当前节点的备份。2.6 流程分析结合Roach工具备份调度流图和日志信息分析如下:       整个备份流程的上层代码为python代码,即GaussRoach.py,master进程的创建和agent进程的拉起都是由python侧完成的。备份的配置和参数部分检查过程同样是由python侧代码完成。各个节点agent进程被拉起之后,C侧代码进行具体的业务操作。C侧代码运行起来之后,可以通过ps ux到gs_roach进程查看进程状态。No.Step①Creating Thread Roach Agent②RAGENT_EXEC_PREPARING_METADATA come③Enter the callback of rowstore copy④performBackup enter⑤Start delay ddl recycle before col file copy⑥Setting agent state to [AGNET_CREATING_BARRIER]⑦RAGENT_EXEC_BACKUP_XLOGFILES come⑧Enter the callback of colstore copy⑨Stop delay ddl recycle after having copied all col files⑩Setting Master state to [PERFORM_BOOKKEEPING_INFO]②:metadata清单即此次备份的文件清单;只要没有走到③ ,备份是没有开始的;备份时的百分比,并不代表时间维度的备份进度,只代表流程进度;只要没有打印出④ ,说明备份还没有结束,即使进度显示是100%;⑤:在此参数开启后,所有的ddl语句会在逻辑上执行,对物理文件的操作不会立即生效;⑥:create barrier之后的数据变化,将通过xlog记录来备份;⑨:关闭延迟DDL参数后,所有被延迟的对物理文件的操作,将会立即执行;2.7 备份集的存储形式备份的数据会进行压缩后写入到rch文件后存储到备份路径下的实例文件夹下,且每个rch文件大小是4GB;存放路径:[存储路径]/roach/backupkey/hostname/,其中存储路径为备份命令中指定的--media-destination的值,backupkey为当前备份开始的时间作为标识某个特定的备份集,hostname为当前节点的hostname。内容如下:Roach压缩文件*.rch的内部结构:控制备份的元数据,元数据存储路径为备份命令中指定的--metadata-destination的值,其路径下内容如下:ini文件中记录着每次备份的元信息{"BackupCount":1,"BackupDetails":[{"S_NO":1,"BackupKey":"20190814_163625","BackupType":"FULL", …….}roach文件夹存储的为特定某个备份的元信息2.8 日志回收       日志是查看代码运行状态和错误定位的重要文件,Roach内核的回收日志只能保证一个日志回收点:$GAUSSLOG/roach/。      Roach日志的管理可分为三类:agent文件夹保存了内核侧生成的日志;controller文件夹保存了python侧的调度信息;frame文件夹保存了双集群容灾过程中python侧代码生成的日志。(1)内核日志缺省情况下,内核日志仅记录警告及以上级别的消息。Roach工具支持的日志级别,及默认只有ERROR和Warning级别日志。执行命令可开启INFO级别日志,--logging –logging-level INFO如果备份或恢复操作失败,可查看控制台中显示的错误汇总,识别发生错误的主机。(2)系统日志Linux记录系统事件至系统日志中。Roach工具将FATAL及ERROR消息记入相同的系统日志文件。例如,在运行SUSE Linux操作系统的设备上,Roach写日志到/var/log/messages文件。(3)安全日志用户可以保存所有活动信息到文件中。安全日志文件包括时间戳,以及备份,恢复和生成文件的详细信息。安全日志文件的文件名称格式如下:roach-agent-security-YYYY-MM-DD_HHMMSS.log。(4)控制器日志控制器日志为python脚本运行日志,用户可以保存控制器日志信息到文件中。控制器日志文件的格式如下:roach-controller-YYYY-MM-DD_HHMMSS.log。例如:roach-controller-2015-12-15_203415.log      遇到故障时,结合打屏信息和相应位置的日志文件,可以快速定位到出错位置,提高解决问题效率。三、总结       备份能解决数据丢失的找回、数据损坏的找回和历史数据找回等功能,是构建容灾方案的基础,如何快速、有效实现大数据备份功能是这个时代一个非常重要的课题。原文链接:https://bbs.huaweicloud.com/blogs/242694【推荐阅读】【最新活动汇总】DWS活动火热进行中,互动好礼送不停(持续更新中)  HOT  【博文汇总】GaussDB(DWS)博文汇总1,欢迎大家交流探讨~(持续更新中)【维护宝典汇总】GaussDB(DWS)维护宝典汇总贴1,欢迎大家交流探讨(持续更新中)【项目实践汇总】GaussDB(DWS)项目实践汇总贴,欢迎大家交流探讨(持续更新中)【DevRun直播汇总】GaussDB(DWS)黑科技直播汇总,欢迎大家交流学习(持续更新中)【培训视频汇总】GaussDB(DWS) 培训视频汇总,欢迎大家交流学习(持续更新中)扫码关注我哦,我在这里↓↓↓
  • [集群&DWS] GaussDB(DWS)集群管理系列: CMS通信机制介绍
    CMS数据库实例CMS即GaussDB(DWS)集群管理模块(Cluster Manager Server)缩写,是管理和监控分布式系统中各个功能单元和物理资源运行情况,确保整个系统稳定运行的组件。CMS模块分为CMS_Primary和CMS_Standby,作为高可用的一部分,CMS主在故障后,备CMS会自动升为主CMS,避免出现CMS单节点故障。此外,CMS能够对CMAgent上报的集群实例状态做仲裁,判断当前状态是否正常,是否需要修复,并下发指令给CMAgent执行。CMS通信对象集群管理中,CM通信主要分为三个对象,分别为:1、CMA:CMA周期性上报实例GTM,CN,DN状态给CMS,并发送心跳,CMS将仲裁结果下发command给CMA,实现实例重启、主备倒换、failover升主、实例build等操作,其中使用消息类型对各个command进行区分。2、cm_ctl:cm_ctl查询集群状态,做switchover、build、query等操作时,需要与cms通信,查询操作由cms返回相关数据,集群使能操作通过cms进行转发。3、CMS主备间通信:CMS主备间通信涉及到集群HA特性,主要用于同步对集群状态监控的数据,并且作为选主操作时候同步信息。CMS通信的基本方式CMS底层使用TCP/IP协议进行通信,socket的建立以及通信过程中的收发使用内部通信库完成。其中CMS会建立两个socket端口,如下图所示,其中端口号小的与CMA和cm_ctl进行通信,端口号大的与cms进行主备通信,两个socket可以区分开来,实现通信模型上互不干扰。tcp        0      0 192.168.233.17:6850     0.0.0.0:*               LISTEN      26087/cm_server tcp        0      0 192.168.226.35:6851     0.0.0.0:*               LISTEN      7632/cm_server此外,由于CMS主备通信的连接数有限,但是CMA和cm_ctl的连接数较多,所以会使用不同的通信模型。其中前者使用select模型,后者使用epoll模型+线程池技术。两者都是典型的I/O多路复用技术,即当socket具备读或者写的状态,会触发相应的事件通知,这样多个文件描述符就能够并行的完成相应的工作,提高系统的并发程度。CMS通信的实现1、线程池模型为了提高系统的并发程度和效率,当集群节点数增多,并且在运行过程中需要频繁查询集群状态时候,需要有大量的CMA和cm_ctl对CMS进行访问。CMS为此开辟了专门的线程负责线程池的管理工作,并使用epoll IO多路复用机制。具体线程池接入流程如下图所示:1)cms主线程2)CMS线程池事件处理流程以上流程图可以看出,CMS主线程主要负责分发事件,每个cm_ctl、cma的连接由线程池内线程去完成。2、select方式CMS主备之间由于通信压力不大,只有两个实例之间通讯,所以主要采用select轮询的方式。每一个HA线程周期,从socket中select已经具备通信条件的文件描述符,完成消息的收发,实现命令消息同步和选主消息的发送。原文链接:https://bbs.huaweicloud.com/blogs/241853【推荐阅读】【最新活动汇总】DWS活动火热进行中,互动好礼送不停(持续更新中)  HOT  【博文汇总】GaussDB(DWS)博文汇总1,欢迎大家交流探讨~(持续更新中)【维护宝典汇总】GaussDB(DWS)维护宝典汇总贴1,欢迎大家交流探讨(持续更新中)【项目实践汇总】GaussDB(DWS)项目实践汇总贴,欢迎大家交流探讨(持续更新中)【DevRun直播汇总】GaussDB(DWS)黑科技直播汇总,欢迎大家交流学习(持续更新中)【培训视频汇总】GaussDB(DWS) 培训视频汇总,欢迎大家交流学习(持续更新中)扫码关注我哦,我在这里↓↓↓
  • [存储] GaussDB(DWS)数据利器GDS探析
    【摘要】 GDS是GaussDB(DWS)提供的一个数据导入导出工具,可在支持多种场景下的数据迁移业务,如异型数据库之间、两个集群之间等。GDS性能较高,单核处理能力上限约400MB/s,相比copy、\COPY工具性能更优、运行更稳定、容错性更强。1. GDS定位GDS是GaussDB(DWS)提供的一个数据导入导出工具,可在支持多种场景下的数据迁移业务,如异型数据库之间、两个集群之间等。GDS性能较高,单核处理能力上限约400MB/s,相比COPY、\COPY工具性能更优、运行更稳定、容错性更强。2. GDS根基GDS基于FDW,全称是Foreign Data Wrapper(外部数据包装器)。这个功能是PostgreSQL 9.1首次引入的,实现了部分SQL/MED的特性。 2.1 什么是FDW顾名思义,这个功能与数据库外部的数据有关系,对于外数据的具体描述是通过外部表来定义的。以GDS外部表创建语句为例说明外部表的结构:CREATE FOREIGN TABLE [ IF NOT EXISTS ] table_name( [ { column_name type_name POSITION(offset,length) | LIKE source_table } [, ...] ] )SERVER gsmpp_server OPTIONS ( { option_name ' value ' } [, ...] )[ { WRITE ONLY | READ ONLY }][ WITH error_table_name | LOG INTO error_table_name][REMOTE LOG 'name'][PER NODE REJECT LIMIT 'value'][ TO { GROUP groupname | NODE ( nodename [, ... ] ) } ];可以看出,外部表可以分为三部分:字段定义、server定义、options定义。其中:(1)字段属性定义与本地表定义方式类似,甚至可以使用like L_TBL等语法进行定义;(2)server定义,需要使用CREATE SERVER xxx_server创建;(3)options选项,由与该外表相关的FDW实现决定。在GDS使用过程中,安装自定义FDW、创建server等配置都是在initdb阶段执行,无须用户额外设置。Postgres现在有很多FDW扩展,其中postgres_fdw、file_fdw是由官方全球开发组维护,postgres_fdw可用于访问远程PostgreSQL服务器。下图展示了FDW的执行过程[1]。① 查询分析模块为输入的SQL创建一棵查询树;② 计划器(或执行器)连接到远程服务器;③ 执行EXPLAIN命令以估算计划路径的代价;④ 计划器按照计划树创建出纯文本SQL语句;⑤ 执行器将纯文本SQL语句发送到远程服务器并接收结果。2.2 GDS自定义FDW根据导入导出场景,GaussDB(DWS)实现了自定义的FDW扩展——dist_fdw。dist_fdw运行于GaussDB内核之中,在initdb时进行安装,所以一般情况下对用户是透明的。3. 多角度缔造高性能3.1 多线程工作模式GDS使用多线程模式,由主线程负责接收请求,然后分配给工作线程进行具体的业务处理,可以并发处理导入导出业务。主线程与工作线程通过UnixSocket进行通信,通信内容包括:分派新任务、停止工作线程、工作线程状态上报等。每个线程可承载多个导入导出业务,通过与事件消息驱动机制相结合,实现高速网络通信,确保业务执行高性能、高并发。3.2 事件消息驱动机制GDS采用事件驱动模型,选择当前系统可支持的最高效的多路复用机制(epoll、poll、select等)。3.3 大文件导入优化对于超大文件的导入,如果仍然与普通文件一样,继续采用串行方式导入,必然会成为业务瓶颈,导致数据迁移、备份等过程的无限延长,无法充分发挥多核机器、GDS多线程架构的优势。针对该场景,GDS引入分片导入机制,实现并行导入,充分发挥软硬件性能,减少业务阻塞,减少数据迁移耗时。该功能针对本地文件的导入场景,需通过外表file_sequence参数进行相应设置。该参数格式为file_sequence '文件被拆分的总数-当前分片' 。例如:file_sequence '3-1' 表示导入的文件在逻辑上被拆分成3份,当前外表导入的数据为第一个分片上的数据。file_sequence '3-2' 表示导入的文件在逻辑上被拆分成3份,当前外表导入的数据为第二个分片上的数据。file_sequence '3-3' 表示导入的文件在逻辑上被拆分成3份,当前外表导入的数据为第三个分片上的数据。这里给出一个使用示例:-- step1. 创建目标表CREATE TABLE gds_widetb_1 (city integer, tel_num varchar(16), card_code varchar(15), phone_code vcreate table pipegds_widetb_3 (city integer, tel_num varchar(16), card_code varchar(15), phone_code varchar(16), region_code varchar(6), station_id varchar(10), tmsi varchar(20), rec_date integer(6), rec_time integer(6), rec_type numeric(2), switch_id varchar(15), attach_city varchar(6), opc varchar(20), dpc varchar(20));--step2. 创建带有file_sequence字段的外表。CREATE FOREIGN TABLE gds_csv_r_1( like gds_widetb_1) SERVER gsmpp_server OPTIONS (LOCATION 'gsfs://127.0.0.1:8781/wide_tb.txt', FORMAT 'text', DELIMITER E'|+|', NULL '', file_sequence '3-1');CREATE FOREIGN TABLE gds_csv_r_2( like gds_widetb_1) SERVER gsmpp_server OPTIONS (LOCATION 'gsfs://127.0.0.1:8781/wide_tb.txt', FORMAT 'text', DELIMITER E'|+|', NULL '', file_sequence '3-2');CREATE FOREIGN TABLE gds_csv_r_3( like gds_widetb_1) SERVER gsmpp_server OPTIONS (LOCATION 'gsfs://127.0.0.1:8781/wide_tb.txt', FORMAT 'text', DELIMITER E'|+|', NULL '', file_sequence '3-3');--step3. 将wide_tb.txt并发导入到gds_widetb_1。\parallel onINSERT INTO gds_widetb_1 SELECT * FROM gds_csv_r_1;INSERT INTO gds_widetb_1 SELECT * FROM gds_csv_r_2;INSERT INTO gds_widetb_1 SELECT * FROM gds_csv_r_3;\parallel off3.4 SMP特性支持导入场景SMP特性通过算子并行来提升性能,本质上是一种利用富余资源来换取时间的方案,计划并行之后会占用更多的系统资源,包括CPU、内存、网络、I/O等等。在合适的场景以及资源充足的情况下,能够起到较好的性能提升效果。SMP支持自适应特性,该特性会根据当前资源和查询特征,动态选取最优的并行度。SMP特性支持支持GDS导入的外表扫描并行,当集群资源充足时,可以发挥各节点性能,加速导入执行效率。4. 全方位丰富功能4.1 容错机制提供了强大的容错机制,包括错误默认处理、错误表、错误日志等多种方式,减少数据导入导出异常中止的情况,方便用户事后查询分析。4.2 编码解析支持多种类型的字符编码,包括UTF-8、GBK、ASCII、LATIN1等。4.3 多字符字段/换行分割符对于外表属性,分隔符delimiter、行分隔符eol,既兼容原有的逗号、\n等默认方式,还支持用户自定义多字符分隔符,最多可支持10个字节。在场景复杂、噪声较多、数据量很大的场景下,单字符分隔符很容易与数据本身冲突,而使用多字符分隔符,可以减少这种冲突,且可以轻容兼容异构数据库,方便用户进行数据处理。4.4 数据不落地此前GDS只支持本地文件的导入导出,因此无论是数据加工清洗或者是远端数据的导入导出都需要在GDS本地生成一份中间数据,这对用户来说不仅消耗磁盘空间并且很不方便。据此,开发人员对不落地导入导出特性进行了规划和实现,提供了另外一种导入导出方式,不仅节省了用户的磁盘空间而且让GDS的使用变得更加灵活多变。具体使用方式参见用户手册。5. 展望随着数据仓库业务的发展,GDS使用场景日益增多,这就要求GDS仍要不断迭代,充分深入挖掘用户需求,提高产品化程度。继往开来,GDS一批新特性已展开规划,如自动化工具、过程监控工具、云化等等。未来可期,作为GaussDB(DWS)的强有力数据迁移工具,GDS会继续强化,丰富产品生态。【参考文献】[1] [日]铃木启修.PostgreSQL指南——内幕探索[M].电子工业出版社:北京,2019:85-86.原文链接:https://bbs.huaweicloud.com/blogs/237973【推荐阅读】【最新活动汇总】DWS活动火热进行中,互动好礼送不停(持续更新中)  HOT  【博文汇总】GaussDB(DWS)博文汇总1,欢迎大家交流探讨~(持续更新中)【维护宝典汇总】GaussDB(DWS)维护宝典汇总贴1,欢迎大家交流探讨(持续更新中)【项目实践汇总】GaussDB(DWS)项目实践汇总贴,欢迎大家交流探讨(持续更新中)【DevRun直播汇总】GaussDB(DWS)黑科技直播汇总,欢迎大家交流学习(持续更新中)【培训视频汇总】GaussDB(DWS) 培训视频汇总,欢迎大家交流学习(持续更新中)扫码关注我哦,我在这里↓↓↓
  • [集群&DWS] GaussDB(DWS)集群管理系列:CM启停功能的原理、流程和关键日志
    【摘要】 本文介绍了集群管理组件CM启停集群的原理、流程和关键日志,CM_CTL模块通过启动、停止命令删除或生成启停文件,CM_AGENT模块通过循环检查启停文件是否存在以及其他启动条件执行实例的拉起或停止操作。CM启停集群功能介绍一 CM_CTL模块cm_ctl是GaussDB(DWS)提供的用来控制集群服务的工具。启动集群和停止集群是cm_ctl的重要功能,其功能的实现主要通过启停文件实现:集群启停文件 cluster_manual_start实例启停文件 instance_manual_start_X(X是实例编号,例如instance_manual_start_6001)       当启动集群、节点、实例时,会删除启停文件,当停止集群、节点、实例时,会生成启停文件。通过cm_ctl生成的启停文件中有三行信息,每行为一个数字,第一个字段保留,第二、三个字段分别记录了停止模式和停止等级。启停文件位于$GAUSSHOME/bin下。其中,GAUSSHOME为环境变量。行数字段取值范围说明1保留字段0-2停止模式0:smart发送SIGTERM信号1: fast发送SIGINT信号2: immediate发送SIGKILL信号3停止等级0单实例停止,对应实例级启停文件1单节点停止,对应集群级启停文件2集群级停止,对应集群级启停文件 cm_agent组件不区分停止单节点和停止集群,因此启停文件均为集群级;停止等级仅用于内部识别,不影响实际的停止流程;停止cm_server进程与具体停止模式无关,均发送SIGKILL信号;如果启停文件内容为空,则根据名称判断启停文件级别,并执行默认的停止流程,默认的停止模式为smart;目前不支持通过cm_ctl停止单个cm_server进程,可通过手动生成实例级启停文件的方式控制;以smart方式停止节点或集群时,DN环的停止顺序为先停止备DN,再停止主DN; cm_ctl启停命令:启动集群cm_ctl start启动节点cm_ctl start –n nodeid启动实例cm_ctl start –n nodeid –D datapath停止集群cm_ctl stop停止节点cm_ctl stop –n nodeid停止实例cm_ctl stop –n nodeid –D datapath         以下图中实例6001为例,其启动命令为cm_ctl start –n 1 –D /home/mpp/data/dnP1     具体的启动停止操作将交由cm_agent执行。二、CM_AGENT模块cm_agent是GaussDB(DWS)提供的部署在集群各主机上用来启停和监控各数据库实例进程的集群管理组件,拉起和停止本主机上部署的实例进程是cm_agent的一个重要功能。该功能由常驻的启停线程来完成,根据检测到的启动、停止条件去相应地启动、停止集群,下面对cm_agent的启停流程进行介绍:1. CM Agent启停流程cm_agent的停止实例进程流程如图1所示:                                                             图1cm_agent启动实例进程的流程如图2所示:                                                             图2CM Agent整体的启停流程大致如图1和图2所示,对于不同类型的实例,其启停流程上会有一些差别,下面对不同实例启停的差别进行描述:(1)CM Server: 只有在检查到启停文件存在时才会杀死cm_server进程,而在磁盘、网卡有故障时并不会杀死cm_server进程。(2)CN:对于已经被剔除的CN,不会再对其启动。(3)DN:拉起DN时进行build进程的检查       a. build进程pid>0并且running(正在进行build)       b. build进程pid>0并且not running(即build失败),重新进行build       c. build进程pid<0,重新进行build       d.build进程pid=0, 且DN进程不存在,(build已经完成)拉起DN 2. 关键日志举例日志类型关键字段举例启动日志GTM磁盘或网卡故障disk damged/ nic downstop the gtm instance 1001 due to disk damged or nic downGTM进程不存在但满足启动条件GTM START systemgtm(/home/mpp/data/gtm) is not running,now start, try 0 ! !GTM START system(command:…)CN磁盘故障、网卡故障或CN被剔除disk fault/ nic fault/ droppedkill CN because disk fault or nic fault or be droppedCN无法重启Do not start cnDo not start cn because cn on current node has been manually stopped.CN进程不存在但满足启动条件CN START systemcoordinate(/home/mpp/data/cn) is not running, now start, try 0 times!CN START system(command:…)DN启停文件存在manually stoppedDatanode 6001 is manually stopped. Do not perform start check.cm_server因端口或磁盘原因无法重启would not be startedCM Server 1 would not be started due to port conflict. cm_server启停文件存在无法重启Do not start cm serverDo not start cm server because cm server on current instance has been manually stopped.拉起cm_serverCM_SERVER START systemCM_SERVER START system(command:…).停止日志检测到集群启停文件cluster manual start fileFound the cluster manual start file, set the shutdown flag.所有实例正常停止all the instancesall the instances have stopped!仍存在实例进程Stopping checkall the instances原文链接:https://bbs.huaweicloud.com/blogs/233442【推荐阅读】【最新活动汇总】DWS活动火热进行中,互动好礼送不停(持续更新中)  HOT  【博文汇总】GaussDB(DWS)博文汇总1,欢迎大家交流探讨~(持续更新中)【维护宝典汇总】GaussDB(DWS)维护宝典汇总贴1,欢迎大家交流探讨(持续更新中)【项目实践汇总】GaussDB(DWS)项目实践汇总贴,欢迎大家交流探讨(持续更新中)【DevRun直播汇总】GaussDB(DWS)黑科技直播汇总,欢迎大家交流学习(持续更新中)【培训视频汇总】GaussDB(DWS) 培训视频汇总,欢迎大家交流学习(持续更新中)扫码关注我哦,我在这里↓↓↓
  • [SQL] GaussDB(DWS)集群后台UDF进程异常
    【摘要】 本帖通过简单示例介绍UDF进程异常的排查和处理方式。背景:使用UDF出现报错,后台查看集群UDF进程发现进程异常。本帖通过简单示例介绍UDF进程异常的排查和处理方式,示例中用到的数据、路径配置、主机名等信息均为测试环境信息。首先,通过以下命令查看集群UDF进程状态:cm_ctl query -CvF结果如下:[  Fenced UDF State   ]node         state--------------------1  ASG003    Down2  host17967 Down3  host17995 Down发现UDF进程处于异常状态,查看cm_agent日志(在$GAUSSLOG/cm/cm_agent目录下)发现如下内容:StartAndStop LOG: process (secbox) is not running, path is xxxx, have_found is 0该日志说明secbox.conf的配置存在问题,进入$GAUSSHOME/secbox路径下,查看secbox.conf配置:# read/write src_path [dst_path][mount_path]            read    /dev[mount_path]            read    /sys[mount_path]            read    /bin[mount_path]            read    /sbin[mount_path]            read    /usr/bin[mount_path]            read    /lib[mount_path]            read    /lib64[mount_path]            read    /usr/lib[mount_path]            read    /usr/lib64[mount_path]            read    /usr/local[mount_path]            read    /usr/share[mount_path]            read    /etc[mount_path]            read    /var[mount_path]            read    /var/log[mount_path]            read    /var/lkp发现该配置中/var/lkp路径不存在,导致UDF进程拉起失败,注释或删除此条配置,几秒后观察本节点UDF进程恢复为Normal状态:[  Fenced UDF State   ]node         state--------------------1  ASG003    Down2  host17967 Normal3  host17995 Down说明配置已生效,按照同样的方法对其他节点修改secbox.conf文件,问题解决。[  Fenced UDF State   ]node         state--------------------1  ASG003    Normal2  host17967 Normal3  host17995 Normal原文链接:https://bbs.huaweicloud.com/blogs/233075【推荐阅读】【最新活动汇总】DWS活动火热进行中,互动好礼送不停(持续更新中)  HOT  【博文汇总】GaussDB(DWS)博文汇总1,欢迎大家交流探讨~(持续更新中)【维护宝典汇总】GaussDB(DWS)维护宝典汇总贴1,欢迎大家交流探讨(持续更新中)【项目实践汇总】GaussDB(DWS)项目实践汇总贴,欢迎大家交流探讨(持续更新中)【DevRun直播汇总】GaussDB(DWS)黑科技直播汇总,欢迎大家交流学习(持续更新中)【培训视频汇总】GaussDB(DWS) 培训视频汇总,欢迎大家交流学习(持续更新中)扫码关注我哦,我在这里↓↓↓
  • [维护宝典] Kafka分区未同步
    一、          节点故障或磁盘下线1.      Kafka节点服务异常通过FusionInsight Manager页面,选择“集群->Kafka”,查看当前Kafka集群当前状态,状态是否是良好;如果状态不是良好,说明Kafka服务异常。2.      磁盘下线通过FusionInsight Manager页面查看告警信息,是否有“Kafka数据目录状态异常”的告警,如果有,server.log日志分析告警产生原因,重启数据目录异常节点。二、          网络异常检查网络是否正常方法如下:使用ping -s 15000 IP命令查看是否有网络丢包,如果网络延迟大于5ms,说明网络延迟高。使用scp从客户端传输一个大文件到kafka服务侧节点,查看传输速率。一般,未完全同步的分区总数监控曲线一直在变化或者通过kafka-topics.sh  --zookeeper zk业务IP:24002/kafka --describe --under-replicated-partitions命令查询处理的未完全同步的分区一直在变化,网络原因的可能性比较大。三、          副本线程下线1.     查看未完全同步分区所在节点执行kafka-topics.sh  --zookeeper zk业务IP:24002/kafka --describe --under-replicated-partitions命令查看所有未完全同步的分区,对比Replicas和ISR列表中的节点,判断未同步的分区是否集中在一个或者几个节点上。例如,下图中ISR列表中都是3未同步。    2.     查看节点信息执行kafka-broker-info.sh  --zookeeper zk业务IP:24002/kafka查看未同步分区所在节点。3.     Kafka配置页面查看“num.replica.ers”的配置大小。4.     切omm用户打jstack信息根据第二步获取的节点IP,连上此节点,su - omm切omm用户,jps |grep Kafka获取Kafka进程的pid,执行“jstack -l kafkapid >>文件名”,然后cat jstack文件|grep ReplicaFetcherThread-查看同步线程。注意:一个副本同步线程的格式如:ReplicaFetcherThread-tid-bid,tid代表一个线程编号,如果配置多个(由服务端配置参数num.replica.ers决定),这个线程号会从0开始依次增加;bid表示leader所在节点的broker-id,如果两个broker之间存在主副本关系,比如:leader在broker-5上,follower在broker-6上,那么broker-6至少会有一个线程名为ReplicaFetcherThread-0-5;如果num.replica.ers配置为2,broker-6 可能会存在两个副本同步线程ReplicaFetcherThread-0-5,ReplicaFetcherThread-1-5。一个节点理论上能够出现的副本同步线程个数为num.replica.ers *(集群broker实例个数 - 1)。但并不是num.replica.ers配置多少就一定会出现这么多个副本同步线程,线程的数量会根据当前broker节点的分区总数来决定,如果节点上面的副本数很少,kafka会判定分区少而没有必要启动这么多副本同步线程,则副本同步线程个数可能少于num.replica.ers *(broker实例个数 - 1)。通常建议num.replica.ers值配置为3即可,太大会影响CPU的使用率)。5.     查看分区同步线程是否下线。如果未查询到同步线程,或者num.replica.ers配置为1且同步线程个数小于(broker实例个数 - 1)的值,或者没有查找此节点到未同步的leader节点的线程,则有同步线程下线。具体可根据未完全同步分区开始上升的时间去server.log日志中排查原因,可搜索“Stopped”、“Shutdown”等关键字查找“ReplicaFetcherThread-”开头的线程是否异常下线。6.     副本线程下线相关BUG1) java.nio.BufferOverflowException2) unexpected offset in append to3) Attempt to append to a full index4) Trying to roll a new log segment for partition以上BUG均在6518及之后版本解决。四、          节点异常退服节点退服前未将退服节点上的分区迁移至未退服节点,具体查看方式是执行kafka-topics.sh  --zookeeper zk业务IP:24002/kafka --describe --under-replicated-partitions命令查看所有未完全同步的分区,对比Replicas和ISR列表中的节点,判断未同步的分区是否集中在一个或者几个节点上,如果是,执行kafka-broker-info.sh  --zookeeper zk业务IP:24002/kafka查看节点是否在此列表中,如果没有,确认之前是否退服过节点,如果是,可以确定是退服节点导致。解决办法是迁移退服节点上的分区到正常节点。五、          Kafka节点压力大iostat -d -x 1查看CPU参数idle和IO参数util,idle值越高,CPU越空闲,util值越高,IO使用率越高。如果idle值小于20%,top -Hp kafkaPid查看CPU使用率高的线程,打jstack日志分析具体的原因;如果util值大于80%,查看磁盘对应的读写速率、await和svctm的大小判断对IO影响大的原因,如果读写速率比较大,排查kafka读写请求和延时,如果awati远大于svctm,IO队列太长,应用响应时间很慢。Kafka的数据流量监控中在未同步分区出现时有没有陡增,字节输入输出流量是否达到网络阈值。
  • [存储] 未雨绸缪,数据保护之NBU介质备份
    一、简介企业要想避开自然灾难和站点中断的影响,必须将数据副本远程备份至异地机器中。 这样当生产站点发生重大灾难事故时候,本地的生存存储与备份存储数据可能都会丢失,此时需要从异地备份存储上恢复数据,从而保证数据不丢失。Netbackup 是目前金融行业使用最广的备份软件之一(简称NBU),是Veritas(赛门铁克)主要产品 。华为GaussDB目前已支持NBU介质的备份与恢复,本文主要描述了华为GaussDB数据库和NetBackup对接进行备份、恢复的配置方法与性能调优方法。二、NBU部署方式当前GaussDB NBU备份方案支持两种部署架构,分别为侵入式部署于非侵入式部署。NBU侵入式部署当GaussDB所在集群支持NBU系列软件安装时,部署方式采用NBU侵入式部署,部署结构如下图:NBU侵入式部署方案可以借阅 【GaussDB对接NBU备份环境配置指南】具体使用方法如下:注意:--media-destination: 该参数为NBU policy名称--metadata-destination: 元数据目录(本地路径)--prior-backup-key: 该参数为增量备份依赖的备份集--backup-key: 该参数指定恢复备份集1、全量备份:python $GPHOME/script/GaussRoach.py -t backup --master-port 55000 --media-destination nbu_policy --media-type NBU --metadata-destination  /data1/roachbackup/metadata  --parallel-process 32、增量备份python $GPHOME/script/GaussRoach.py -t backup --master-port 55000 --media-destination nbu_policy --media-type NBU --metadata-destination  $GAUSSHOME/roachbackup/metadata  --parallel-process 3 --prior-backup-key 20200912_0833243、全量/增量恢复python $GPHOME/script/GaussRoach.py -t restore --clean --master-port 55000 --media-destination nbu_policy --media-type NBU --metadata-destination  /data1/roachbackup/metadata  --backup-key 20200912_0833244、单表备份python $GPHOME/script/GaussRoach.py -t backup --master-port 25990 --media-destination nbu_policy --media-type NBU --metadata-destination  $GAUSSHOME/tablebackup/metadata --dbname testdb --tablename test --agent-port 349905、单表恢复python $GPHOME/script/GaussRoach.py -t restore --clean --master-port 25990 --media-destination nbu_policy --media-type NBU --metadata-destination  $GAUSSHOME/tablebackup/metadata --dbname testdb --tablename test --agent-port 34990  --backup-key 20190826_1516006、多表备份python $GPHOME/script/GaussRoach.py -t backup --master-port 9500 --media-destination nbu_policy --media-type NBU --metadata-destination  $GAUSSHOME/roachbackup/metadata --logical --agent-port 7000 --dbname testdb --table-list /home/omm/table.list7、多表恢复python $GPHOME/script/GaussRoach.py -t restore --clean --master-port 9500 --media-destination $GAUSSHOME/roachbackup/mediadata --media-type nbu_policy --metadata-destination  $GAUSSHOME/roachbackup/metadata --logical --agent-port 7000 --dbname testdb --table-list /home/apdba/table_list.txt --backup-key  20190511_183652 -8、数据库级备份python $GPHOME/script/GaussRoach.py -t backup --dbname testdb --agent-port 7000 --metadata-destination $GAUSSHOME/roachbackup/metadata --media-destination nbu_policy --master-port 9500 --media-type NBU9、数据库级恢复python $GPHOME/script/GaussRoach.py -t restore --dbname testdb --agent-port 7000 --metadata-destination $GAUSSHOME/roachbackup/metadata --media-destination nbu_policy --master-port 9500 --media-type NBU --backup-key key 20190511_193122NBU非侵入式部署当前NBU系列软件只支持x86机器,NBU非侵入式部署则支撑NBU系列软件无法在ARM、欧拉系统安装的场景。如下图所示,假如已有3节点GaussDB集群,Roach备份工具将本节点的集群数据通过TCP发送到远端NBU Media Server机器。每台NBU Media Server上面同时安装NBU Client,并部署Roach client组件,后者接收集群内Roach进程发来的备份数据,不落盘方式通过XBSA接口转发给本机的NBU Client,完成NBU备份。恢复流程也类似,只是数据流相反。Roach client插件安装:从DWS管控面的连接管理界面下载Roach client组件包到集群本地,然后拷贝出来。如下:useradd omm passwd omm   # 输入密码 su - omm cd /data/omm/ # 变更为本地安装目录, 将Roach client安装tar包拷贝至此目录下 mkdir roach_client tar -zxvf GaussDB-8.1.0-REDHAT-x86_64bit-RoachClient.tar.gz -C roach_client cd /data/omm/roach_client/bin/source roach_client_env./roach_client -p ip:8888 -H 0/0 -D -l roach_client.log  # ip为当前部署roach_client机 ps -ef | grep roach_client # 启动后检查roach_client是否启动成功注意:/roach_client -p ip:8888 -H 0/0 -D -l roach_client.log其中ip为当前部署roach_client机器, 8888为roach_client开放端口,用于沙箱内集群各节点和NBU Media Server之间TCP通信传输备份文件 ; -l 为指定日志路径备份方式:注意:--media-destination: 该参数为NBU policy名称--metadata-destination: 元数据目录(本地路径)--nbu-on-remote:该参数指定部署方式为NBU非侵入式部署--nbu-media-list: 该参数指定NBU Media Server的ip清单,按行输入ip地址--client-port: 该参数指定Roach client插件的对外开放通信端口--prior-backup-key: 该参数为增量备份依赖的备份集--backup-key: 该参数指定恢复备份集1、全量备份:python $GPHOME/script/GaussRoach.py -t backup --master-port 55000 --media-destination nbu_policy --media-type NBU --metadata-destination  /data1/roachbackup/metadata  --parallel-process 3 --nbu-on-remote --nbu-media-list /home/Ruby/media.txt --client-port 88882、增量备份python $GPHOME/script/GaussRoach.py -t backup --master-port 55000 --media-destination nbu_policy --media-type NBU --metadata-destination  $GAUSSHOME/roachbackup/metadata  --parallel-process 3 --nbu-on-remote --nbu-media-list /home/Ruby/media.txt --client-port 8888 --prior-backup-key 20200912_0833243、全量/增量恢复python $GPHOME/script/GaussRoach.py -t restore --clean --master-port 55000 --media-destination nbu_policy --media-type NBU --metadata-destination  /data1/roachbackup/metadata  --backup-key 20200912_083324 --nbu-on-remote --nbu-media-list /home/Ruby/media.txt --client-port 88884、单表备份python $GPHOME/script/GaussRoach.py -t backup --master-port 25990 --media-destination nbu_policy --media-type NBU --metadata-destination  $GAUSSHOME/tablebackup/metadata --dbname testdb --tablename test --agent-port 34990  --nbu-on-remote --nbu-media-list /home/liding/nbu/media.txt --client-port 90005、单表恢复python $GPHOME/script/GaussRoach.py -t restore --clean --master-port 25990 --media-destination nbu_policy --media-type NBU --metadata-destination  $GAUSSHOME/tablebackup/metadata --dbname testdb --tablename test --agent-port 34990  --backup-key 20190826_151600  --nbu-on-remote --nbu-media-list /home/liding/nbu/media.txt --client-port 90006、多表备份python $GPHOME/script/GaussRoach.py -t backup --master-port 9500 --media-destination nbu_policy --media-type NBU --metadata-destination  $GAUSSHOME/roachbackup/metadata --logical --agent-port 7000 --dbname testdb --table-list /home/omm/table.list --nbu-on-remote --nbu-media-list /home/liding/nbu/media.txt --client-port 90007、多表恢复python $GPHOME/script/GaussRoach.py -t restore --clean --master-port 9500 --media-destination $GAUSSHOME/roachbackup/mediadata --media-type nbu_policy --metadata-destination  $GAUSSHOME/roachbackup/metadata --logical --agent-port 7000 --dbname testdb --table-list /home/apdba/table_list.txt --backup-key  20190511_183652 --nbu-on-remote --nbu-media-list /home/liding/nbu/media.txt --client-port 90008、数据库级备份python $GPHOME/script/GaussRoach.py -t backup --dbname testdb --agent-port 7000 --metadata-destination $GAUSSHOME/roachbackup/metadata --media-destination nbu_policy --master-port 9500 --media-type NBU  --nbu-on-remote --nbu-media-list /home/liding/nbu/media.txt --client-port 90009、数据库级恢复python $GPHOME/script/GaussRoach.py -t restore --dbname testdb --agent-port 7000 --metadata-destination $GAUSSHOME/roachbackup/metadata --media-destination nbu_policy --master-port 9500 --media-type NBU --backup-key key 20190511_193122  --nbu-on-remote --nbu-media-list /home/liding/nbu/media.txt --client-port 9000三、NBU流程概述备份数据流NBU 一般涉及NBU Master Server、NBU Media Server、NBU client,属于一个three-trie结构。本章节主要介绍NBU进程工作原理,方便使用者、开发者了解NBU备份流程,排查问题。下图中为通过备份所涉及的数据流向基本备份过程:1、启动备份方式:当 nbpem 服务检测到某项作业到了启动时间时,将开始进行预定的备份操作。nbpem会检查到了启动时间的预定客户机备份的策略配置。如果管理员在 NetBackup 管理控制台中选择了手动备份选项,将开始进行即时手动备份。这会使 bprd 联系 nbpem,然后 nbpem 将处理管理员所选择的策略、客户机和日程表。当客户机上的用户通过该客户机上的用户界面(或者通过 bpbackup 或xbsa系列接口)启动备份或回复时,将开始进行用户控制的备份或回复操作。这将调用该客户机的 XBSA程序,该程序向主服务器上的请求后台驻留程序 bprd发送请求。当前Roach NBU介质备份采用这种启动方式。2、接收备份任务: 响应进程(bprd)接收到客户端的备份请求,bprd: request manager请求管理器:     bprd是Master Server的守护进程,bprd进程主要负责对客户机请求作出响应,并将并向nbjm发出 job请求,用于提交备份并获取job ID。3、将请求转发个策略执行管理器nbpmnbpem: policy execution manager策略执行管理器    策略执行管理器服务 (nbpem) 执行以下操作:    a. 通过nbproxy从 bpdbm 中获取策略列表, 查询到有效的备份policy的是否存在;    b、向 nbjm 提交当前已到预定启动时间的所有作业(按照schedule执行时间的策略)。4、为备份job分配资源a、nbjm(job manager作业管理器)接收到任务后,nbjm首先会与bpjobd通信,将此job添加至job列表中,此时在Activity Monitor中该job以queue状态可见。b、nbjm通过nbrb 请求资源,nbrb负责分配资源以响应来自 nbjm 的请求。并从 nbemm (企业介质管理器服务)获取物理资源,并管理逻辑资源,如多路复用组、每个客户机的最多作业数、每个策略的最多作业数。 当nbrb进程从nbemm获取到所需资源时,会返回通知nbjm资源已分配。b、当nbrm资源分配完成后,nbjm会调用 image database 创建临时快照文件,此时该job会在Activity Monitor中该job以active状态可见。5、开始备份a、当job处于active状态后,nbjm通过bpcompatd与NBU Media Server上的客户端服务(bpcd)进行连接,其中bpcompatd服务通过专用小交换机(PBX)和NetBackup旧式网络服务(vnetd)创建连接。b、bpcd进程是NBU Media Server上的守护进程,允许Master Server或NBU Client启动程序。bpcd接收到连接后会启动Netbackup 备份恢复管理器(bpbrm)。b、bpbrm进程服务通过PBX与vnetd与NBU client机器上的bpcd进程建立连接,启动NBU client机器上的bpbkar,其中bpbkar负责生成备份image,并将image数据发送至NBU Media Server上的bpdrm,对于每个备份或恢复job,都会在NBU Media Server上启动一个bpbrm实例用于传输image数据。bpdrm进程会启动磁带/磁盘管理进程bptm,对于磁盘介质,bptm直接与磁盘通信。对于磁带介质,bptm保留驱动器并向逻辑磁带接口守护程序(ltid)发出安装请求。 ltid服务调用机械手驱动器守护程序(txxd,其中xx根据所使用的机械手的类型而异)。 txxd守护程序将安装请求传达给机械手控制守护程序(txxcd),后者将安装介质。6、结束备份bpbkar服务通过bptm发送备份数据,以将其写入介质存储或磁盘存储。 备份完成后,将通知nbjm并将消息发送到bpjobd。此时job在“Activity Monitor”中显示为“done”。 nbjm服务还会将作业退出状态报告给nbpem,nbpem将重新计算作业的下一个到期时间。四、XBSA相关接口NBU软件提供的libxbsa64.so动态库(实现了标准的XBSA系列接口),将本地数据传送到NBU服务器,然后由NBU服务器负责落盘到磁带介质上。 GaussDB的专用备份工具Roach,负责调用libxbsa64.so库将本地数据库文件备份到远端NBU服务器。 本章节则主要针对开发者,介绍XBSA系列接口。备份相关接口备份过程中涉及的XBSA相关接口主要如下:BSAQueryApiVersion:该接口用于确定Netbackup XBSA接口的当前版本。BSAInit:该接口用于对XBSA应用程序进行身份验证,与NetBackup XBSA接口建立session会话,并为调用者的后续API调用建立环境。注意,BSAInit不支持嵌套创建session会话。BSABeginTxn:该接口用于创建一个事物,这里的事物和数据库事物概念相似,BSABeginTxn()调用向NetBackup XBSA接口指示作为原子单位执行的一个或多个操作的开始,即所有操作将成功或没有成功。可以将一个动作假定为为特定目的而进行的单个函数调用或一系列函数调用。例如,一个BSACreateObject()调用后跟多个BSASendData()调用并以BSAEndData()调用终止可以被视为单个操作。 在正常使用中,BSABeginTxn()调用总是与随后的BSAEndTxn()调用耦合。如果在事务期间调用BSATerminate(),则事务中止。注意,BSABeginTxn不支持嵌套创建事物。BSACreateObject:BSACreateObject调用在NetBackup中创建一个XBSA对象。 该调用将启动NetBackup XBSA接口与NetBackup服务器之间的通信。然后可以将XBSA对象数据传递到内存缓冲区中。BSACreateObject调用中的dataBlockPtr参数允许调用者获取有关NetBackup XBSA接口所需的缓冲区结构的信息。BSASendData:BSASendData()将字节数据流发送到缓冲区中的NetBackup XBSA接口。如果要发送的字节数据流很大,则可以多次调用BSASendData()。此调用只能在BSACreateObject()或另一个BSASendData()调用之后使用。BSAEndData:调用方在调用BSACreateObject之后调用零次或多次BSASendData,当前备份文件传输完毕后调用BSAEndData,用于通知Netbackup服务器当前文件传输结束BSAEndTxn:BSAEndTxn与BSABeginTxn耦合使用,以标识将被视为事务的API调用或一组API调用。。BSATerminate:BSATerminate调用终止与NetBackup XBSA接口的会话,该接口由BSAInit调用对应,释放当前session会话获取的所有资源。如果在事务内调用BSATerminate(),则事务中止。恢复相关接口恢复过程中涉及的XBSA相关接口主要如下:BSAQueryObject:BSAQueryObject调用从NetBackup XBSA界面启动有关NetBackup XBSA对象文件的信息请求。查询结果由查询描述符中指定的搜索条件确定。在BSA_ObjectDescriptor(由objectDescriptorPtr参数引用)中返回满足查询搜索条件的第一个XBSA对象的XBSA对象描述符。BSAGetData:BSAGetData从NetBackup XBSA接口请求XBSA对象文件数据。在BSAGetObject()调用之后或在其他BSAGetData调用之后使用此调用。五、问题定位使用Roach工具NBU备份发生故障时,可通过以下思路进行问题定位NBU管理控制界面activity monitor可显示相关的备份、恢复job。 job类型分为三类:蓝色站立人性:表示该次备份/恢复操作已成功执行完毕;绿色跑步人形:表示该次备份/恢复操作正在执行;红色x形:表示该次备份/恢复操作失败,可根据Status查询NBU官方文档获取错误相关原因;例如上图中失败job返回码为13,则可根据文档信息定位排查原因若NBU界面无失败job,则一般问题出现在了Roach侧,可根据Roach日志进行定位。六、参数调优Roach工具目前支持两种NBU部署结构,分别为NBU侵入式部署于NBU非侵入式部署,两种部署方式的参数调优分别如下:1、通用参数调优Maximum concurrent jobs此值指定了对应存储单元上最大作业数量,取值范围为1-256,例如准备将三个备份作业发送到存储单元,并将“最大并发作业数”设置为两个。前两个作业开始,而第三个作业等待。Maximum vault jobs:此属性指定在master server上允许活动的最大活跃job数量。如果达到了允许活动的job限制,则将后续的kob排队,并且它们状态在“活动监视器”中显示为“已排队”。此属性设置范围为1~200, 当备份过程并发job数大大超过200,则master server会出现瓶颈,造成任务排队耗时。此时应考虑部署多Master Server模式。设置NET_BUFFER_SZ :在应用Netbackup备份数据到带库时,有一个NET_BUFFER_SZ参数,决定media server与client之间数据传输的缓冲池大小,该参数值默认为32032 bytes,以文件形式保存于%Install_Path/netbackup/目录下。通常默认值都较小,如果希望修改该参数值,则直接修改%Install_Path/netbackup/NET_BUFFER_SZ即可,例如:host-192-168-241-40:/usr/openv/netbackup # echo 65536 > /usr/openv/netbackup/NET_BUFFER_SZhost-192-168-241-40:/usr/openv/netbackup # more /usr/openv/netbackup/NET_BUFFER_SZ65536设置一个足够大的NET_BUFFER_SZ某些情况下能够有效提高备份的速度,推荐在server/client端都设置该参数。2、NBU侵入式部署调优Maximum jobs per client:此值设定每个NBU client发送的并行处理任务数,通常Roach与并行参数相对性,一般设置为DN数+CN数为最佳。3、NBU非侵入式部署调优Maximum jobs per client:此值设定每个NBU client发送的并行处理任务数,通常Roach与并行参数相对性,一般设置为(DN数+CN数)*(Roach client 服务的Roach agent)个数为最佳。4、超时设置超时属性适用于选定的Master server、Media Server以及NBU clientClient connect timeout:此选项指定服务器连接客户端时等待的秒数。默认值为300s。一般Roach备份业务中,建议此值设置为3600s或者更高。此选项适用于NBU Master Server、NBU Media Server、NBU Client。Client read timeout:此选项指定用于客户端读取超时的秒数。此选项适用于NBU Master Server、NBU Media Server。默认值为300s,如果服务器在客户端在此超时时间内没有从客户端得到响应,则备份/恢复任务失败,报错误码13。特别是针对于NBU Job复用场景,文件间隔传输时间超过此值,则备份/恢复任务失败。建议此值设置为3600s或者更高。Media server connect timeout此选项用于指定Master Server连接Media Server的等待超时描述,默认值为300s。建议此值设置为3600s。此选项适用于NBU Master Server、NBU Media Server。原文链接:https://bbs.huaweicloud.com/blogs/223973【推荐阅读】【最新活动汇总】DWS活动火热进行中,互动好礼送不停(持续更新中)  HOT  【博文汇总】GaussDB(DWS)博文汇总1,欢迎大家交流探讨~(持续更新中)【维护宝典汇总】GaussDB(DWS)维护宝典汇总贴1,欢迎大家交流探讨(持续更新中)【项目实践汇总】GaussDB(DWS)项目实践汇总贴,欢迎大家交流探讨(持续更新中)【DevRun直播汇总】GaussDB(DWS)黑科技直播汇总,欢迎大家交流学习(持续更新中)【培训视频汇总】GaussDB(DWS) 培训视频汇总,欢迎大家交流学习(持续更新中)扫码关注我哦,我在这里↓↓↓
  • [虚拟化] Docker个人学习总结
    1 Docker入门基础1.1 容器级虚拟机化技术主机级虚拟化,          Type1:在硬件上安装虚拟机,hyper-v,没有宿主机         Type2:有宿主机及宿主机OS,虚拟机OS与宿主机OS不一样,如Vmware,workstations。容器级虚拟化:实现用户空间和宿主环境空间的隔离,保障了系统安全。在UTS内可以以名称空间互相隔离的,在同一个空间上创建多个名称空间,每个名称空间互相隔离,拥有各自的根文件系统,root用户,PID 和端口范围。       Namespace原生支持UTS、mount、IPC、PID、User、Net。Linux容器化需要内核支持namespace技术。所以容器是Linux内核封装的技术。1.2 Docker和容器关系1.2.1 Linux容器1、隔离与共享一台服务器运行着多个逻辑隔离的服务器进程,谁的运行环境都不希望影响到谁,也就是一个物理机需要虚拟出多个环境或容器,Linux提供一种创建和进入容器的方式,操作系统让应用程序就像在独立的机器上运行一样,但又能共享很多底层的资源。2、实现基础Linux容器功能是基于cgroups和Namespace实现的。(1)cgroups(control groups 控制组)cgroups是将进程分组管理的内核功能,通过cgroups可以隔离进程,同时还可以隔离进程的资源占用(cpu,内存等)情况,在操作系统底层限制物理资源,起到container的作用,进程可用的cpu资源由cpuset指定。(2)NamespaceNamespace让每个进程拥有独立的PID、IPC和网络空间。Namespace是通过clone系统调用来实现的。clone系统调用的第三个参数flags就是通过设置Namespace来划分资源的。Linux一共构建了6种不同的Namespace,用于不同场景下的隔离1.Mount - 隔离文件系统挂载点;2.UTS - 隔离主机名和域名3.IPC - 隔离进程间通信资源4.PID - 隔离PID空间5.Network - 隔离网络接口6.User - 隔离用户/用户组空间1.2.2 LXC基本概念根据Docker布道师Jerome Petazzoni的说法,Docker约等于LXC+AUFS(之前只支持ubuntu时)(作者2015-10-22更新:Docker0.9.0版本开始引入libcontainer,可以视作LXC的替代品)。其中LXC负责资源管理,AUFS负责镜像管理;而LXC包括cgroup、namespace、chroot等组件,并通过cgroup进行资源管理。所以只从资源管理这条线来看的话,Docker、LXC、Cgroup三者的关系是:Cgroup在最底层落实资源管理,LXC在cgroup上封装了一层,Docker又在LXC封装了一层,关系图如图1(b)所示。因此,要想玩转Docker,有必要了解负责资源管理的CGroup和LXC。Jail->vserver(chroot)->LXC, 大规模创建容器很难,管理不方便。1)LXC是什么LinuxContainer容器可以提供轻量级的内核级虚拟化,以便隔离进程和资源,而且不需要提供指令解释机制以及全虚拟化的其他复杂性。容器有效地将由单个操作系统管理的资源划分到孤立的组中,以更好地在孤立的组之间平衡有冲突的资源使用需求。LXC建立在CGroup基础上,我们可以粗略的认为LXC = Cgroup+ namespace + Chroot + veth +用户态控制脚本。LXC利用内核的新特性(CGroup)来提供用户空间的对象,用来保证资源的隔离和对于应用或者系统的资源控制。根据LXC官网(http://linuxcontainers.org/)的描述,LXC具有以下特性:与虚拟化相比,它的优势在于:a)不需要指令级模拟;b)不需要即时(Just-in-time)编译;c)容器可以在CPU核心的本地运行指令,而不需要任何专门的解释机制;d)避免了准虚拟化和系统调用替换中的复杂性。总结来说,就是LXC更加轻量级,具有更小的性能开销、更快的相应时间。linux contains 的技术是linux 内核的代码,并非Docker 开发出来的,Docker或者其他的虚拟化容器都是基于LXC 的技术,在基础的lxc 上包了一层代码,让LXC 更简单、更友好,更加好推广;下面就看下LXC 的三个技术 •chroot: 创建一个虚拟的根目录文件系统 【实质还是调用底层的文件系统】,不过是建立一个虚拟的,可以跟其他容器的虚拟文件系统相互隔离;但共享底层的文件系统•namespace : 命名空间可以提供一个进程相互隔离的独立网络空间,不同的容器间进程pid可以相同,进程并不冲突影响;但可以共享底层的计算和存储(cpu + mem)•cgroups: 实现了对容器的资源分配和限制,比如给容器1分配10core 30G 内存;那这个容器最多用这么大的资源;如果内存超过30G ,会启动swap,效率降低,也可能会被调度系统给kill掉LXC通过namespace进行资源的隔离,Gust1下的进程与Guset2下的进程是独立的,可以看作运行在两台物理机上一样。Contaniner管理工具就是对Guest进行管理的(创建、销毁)。下图是LXC与KVM技术的比较,KVM的优点是一个物理机上可以跑多个操作系统(Guest-OS),然后在每个操作系统运行应用,通过这种方式实现应用的隔离。而使用LXC技术直接可以在Host-OS的基础上实现隔离的。这就是LXC的优势--运行快。但是,如果有两个应用一个是在windows运行的,一个是在linux上运行的,这时只能使用KVM技术来实现了。1.2.2.1 Cgroups基本概念1)Cgroup是什么Cgroups是control groups的缩写,是Linux内核提供的一种可以限制、记录、隔离进程组(process groups)所使用的物理资源(如:CPU, Memory, IO等)的机制。最初由Google的工程师提出,后来被整合进Linux内核。Cgroups也是LXC为实现虚拟化所使用的资源管理手段,可以说没有Cgroups就没有LXC,也就没有Docker。Cgroups最初的目标是为资源管理提供的一个统一的框架,既整合现有的Cpuset等子系统,也为未来开发新的子系统提供接口。现在的Cgroups适用于多种应用场景,从单个进程的资源控制,到实现操作系统层次的虚拟化(OS Level Virtualization)。简单说是把系统级资源分成多个组,每组资源分配到特定用户空间来使用。Cgroups提供以下功能:a)限制进程组可以使用的资源数量(Resource limiting )。比如:Memory子系统可以为进程组设定一个Memory使用上限,一旦进程组使用的内存达到限额再申请内存,就会出发OOM(out of  memory)。b)进程组的优先级控制(Prioritization)。比如:可以使用CPU子系统为某个进程组分配特定CPUshare。c)进程组隔离(Isolation)。比如:使用ns子系统可以使不同的进程组使用不同的namespace,以达到隔离的目的,不同的进程组有各自的进程、网络、文件系统挂载空间。d)记录进程组使用的资源数量(Accounting)。比如:可以使用Cpuacct子系统记录某个进程组使用的CPU时间e)进程组控制(Control)。比如:使用freezer子系统可以将进程组挂起和恢复。2)Cgroup基本概念与术语任务(task):在Cgroups中,任务就是系统的一个进程。控制族群(control group):控制族群就是一组按照某种标准划分的进程,控制族群通常按照应用划分,即与某应用相关的一组进程,被划分为一个进程组,即控制族群(control group)。Cgroups中的资源控制都是以控制族群为单位实现。一个进程可以加入到某个控制族群,也可以从一个进程组迁移到另一个控制族群。一个进程组的进程可以使用Cgroups以控制族群为单位分配的资源,同时受到Cgroups以控制族群为单位设定的限制。层级(hierarchy):控制族群可以组织成hierarchical的形式,既一颗控制族群树。控制族群树上的子节点控制族群是父节点控制族群的孩子,继承父控制族群的特定的属性。控制族群树的示意图如图2所示。子系统(subsystem):一个子系统就是一个资源控制器,比如CPU子系统就是控制CPU时间分配的一个控制器。子系统必须附加(attach)到一个层级上才能起作用,一个子系统附加到某个层级以后,这个层级上的所有控制族群都受到这个子系统的控制。3)Cgroup子系统介绍a)blkio -- 这个子系统为块设备设定输入/输出限制,比如物理设备(磁盘,固态硬盘,USB等等)。b)cpu -- 这个子系统使用调度程序提供对CPU 的 Cgroup 任务访问。c)cpuacct -- 这个子系统自动生成Cgroup中任务所使用的 CPU 报告。d)cpuset-- 这个子系统为 Cgroup中的任务分配独立CPU(在多核系统)和内存节点。e)devices -- 这个子系统可允许或者拒绝Cgroup中的任务访问设备。f)freezer -- 这个子系统挂起或者恢复Cgroup中的任务。g)memory -- 这个子系统设定Cgroup中任务使用的内存限制,并自动生成由那些任务使用的内存资源报告。h)net_cls -- 这个子系统使用等级识别符(classid)标记网络数据包,可允许Linux 流量控制程序(tc)识别从具体cgroup 中生成的数据包。i)ns -- 名称空间子系统。Cgroup具有不同的挂载方法——“多挂载点”和“单挂载点”。子系统“多挂载点”挂载就是指不同子系统的文件挂载在不同的目录下,每个子系统各有一个挂载点,目录结构如图3(a)所示。cgroup对应服务cgconfig默认使用的就是“多挂载点”的方法。“单挂载点”则是指所有子系统的文件都挂载在同一个目录下,所有子系统都统一挂载在一个挂载点,目录结构如图3(b)所示。  1.2.2.2 NamespaceLinux Namespaces机制提供一种资源隔离方案。PID,IPC,Network等系统资源不再是全局性的(在Linux2.6内核以前是全局的),而是属于特定的Namespace。每个Namespace里面的资源对其他Namespace都是透明的。namespace是container中使用到的重要技术之一,是对系统资源的操作上的隔离。使Guest-OS1的操作对Guest-OS2无法产生影响。当然namespace的实现还在完善中,下面是3.8以上的内核实现的namespace。1. Mount namespace是对挂载的文件系统布局进行隔离。图中显示在Namespace1中的进程看到的文件系统的挂载方式是一致的,但是在Mount Namespace2中看到的是一另一种情况。2.IPC:处于同一namespace下的进程才可以进行进程间通信。3. NET NAMESPACE实现网络协议栈上的隔离,在自己的namespace中对网络的设置只能在本namespace中生效4.PID:我们通过fork来创建进程时可以为每个进程指定命名空间。linux下的进程关系是一棵树,所以有了父命名空间和子名字空间之分。在namespace2创建的P2进程有两个pid。第一个是在父命名空间的下的它的PID号,一个是在自己空间下的PID号。之所以有父pid号是因为P2最终还是在父命名空间下运行的,而为进程指定命名空间是为了让P2和P3实现隔离。5. User namespace中使用到了map转换,由于container并不是真正的虚拟化,所以在Guest-OS中创建的root用户会被映射到Host-OS中的普通用户中去。下图中的例子中,root用户在自己的namespace下创建了一个文件,那这个文件的所有者ID应该是0,当时在磁盘上存的时候文件UID会被转换为kuid,并且所有者ID为1000。想说名一点是在Guest-OS下你是个root用户,但是在Host-OS你只不过被转为一个普通用户而已。因为我们知道在Host-OS下已经有一个root用户了。6.PID namespace:linux下的proc目录是对整个系统状态的描述,用户可以通过查看proc目录来了解当前的系统状态。在proc目录下有很多数字,这些数字对应的是系统创建的进程ID,以前我们说进程是看不见摸不着的,但是通过proc目录我们的确可以看到一些关于进程的信息。每个进程下有个ns目录,在目下记录了该进程使用的到namespace。1.2.2.3 Chroot1.  linux chroot 机制的由来•root 用户启动一个daemon在linux 系统上启动一个daemon 必须用root 用户来启动,比如一个web 服务器(nginx/apapce 80端口)是在操作系统的接口(1-1024),只有root 有这个权限来启动这类接口;用root 户启动daemon 的程序也是一个自然的事情。  •安全问题日益变大随着安全的攻击越来越严重,如果任何一个提供TCP 服务的程序出现漏洞,那攻击者就获取到了root 权限,无疑是灾难性的。为了降低这个问题带来的风险,需要主动放弃root 权限,该用一个普通的用户(比如 admin/nobody) 进行运行。这样一旦攻击者获取到了这个程序的权限,也是此时运行用户的权限,对系统造成的危害相对要小。•chroot 机制的引入为了进一步提高系统的安全性,linux 系统引入了chroot 机制;chroot 是一个系统调用,程序可以通过调用chroot的函数库来 更改一个进程所能看到的跟目录  。比如httpd 软件安装在/usr/local/httpd 这个目录下,那这个进程(httpd) 只可以读、写到这个指定的目录: [ usr/local/httpd] ;这样即使攻击者获取进程的权限,也只能读写这个目录下的文件,这样就变的安全了许多,起码不会影响这个台机器其他的进程,和其他的机器的安全问题 。2. chroot 简介chroot 全程是change to root : 其中root 是根目录的意思,也就是改变(linux 根目录是/,也可以理解为设置)一个程序运行时参考的根目录的位置 # 根目录的参考linux 系统(原始的方案)  | 引入chroot 机制/                                 /lxc/usr                            /lxc/usr/bin                            /lxc/bin/sys                            /lxc/sys如上图我们看的一旦使用了chroot ,用户的春心就不是linux 系统的根目录,而是我们指定的/lxc (这个目录可以任意指定),所以chroot 确实可以修改根目录. 3. chroot 机制的意义•增强系统的安全行•指定程序访问的根目录,防止用攻击者可以通过程序的漏洞获取其他目录的读写权限; 4. chroot 机制在虚拟化中的作用chroot 机制因为安全问题才被引入的,但是在LXC 中却启动了举足轻重的作用,因为chroot 机制可以指定虚拟根目录,让不同的容器在不同的根目录下工作; •不同的容器进程参考的根目录不同,相互直接不影响•不同的容器因为共享linux 底层的文件系统,所以容器集成os的功能,实现轻量级!1.2.2.4 LXC总结通过对ns和Cgroups的介绍,一方面可以实现对系统资源的隔离,但是使用就非常不方便涉及代码实践、底层内核调用以及进程克隆等。通过LXC可以实现对这些工具的封装调用,简化了用户使用。但是LXC使用也不是很方便,比如需要创建出一个虚拟环境,通常会执行一个模板脚本,从指定官网下载对应的软件工具,在本地完成安装后,生产名字空间的运行环境。所以LXC的使用比虚拟机也不是很大方便,隔离性也不比虚拟机好。大规模使用和分发也不友好,后面出现docker。Docker是LXC的加强版,相当于是LXC的前端应用工具。容器是内核技术,docker通过简化容器的使用,得以普及。解决方案为镜像。利用容器管理引擎,通过镜像,来创建出名字空间所需的环境。 1.2.3 LXC与docker的比较:容器技术不是模仿硬件,而是在Linux内核里使用cgroup和namespaces来打造轻便的、将近裸机速度的虚拟技术操作系统环境。因为不是虚拟化存储,所以容器技术不会管底层存储或者文件系统,而是你放哪里,它操作哪里。 这从根本上改变了我们如何虚拟化工作负载和应用程序,因为容器速度比硬件虚拟化技术更快,更加便捷,弹性扩容的更加高效,只是它的工作负载要求操作系统,而不是Linux或特定的Linux内核版本。Docker并不是LXC的替代品,Docker的底层就是使用了LXC来实现的。LXC将Linux进程沙盒化,使得进程之间相互隔离,并且能够控制各进程的资源分配。 在LXC的基础之上,Docker提供了一系列更强的功能。不过现在Docker底层已不使用LXC,先后推出libcontainer和runC. 利用LXC做容器管理引擎,将用户空间需要用到的组件打包封装好,成为镜像文件。极大简化了容器的使用难度,使得容器使用得以推广。容器技术一方面给技术带来极大便利,同时也给维护带来很大挑战。 1.3 Docker基础概念1.3.1 docker是什么Docker是一个开源的应用容器引擎,可以轻松的为任何应用创建一个轻量级的、可移植的、自给自足的容器。开发者在本地编译通过的容器可以批量的在生产环境上部署。Docker类似于集装箱,各式各样的货物,经过集装箱的标准化进行托管,而集装箱与集装箱之前没有影响。Docker是一个开放平台,使开发人员和管理员可以在称为容器的松散隔离的环境中构建镜像、交互和运行分布式应用程序,以便在开发、QA和生产环境之间进行高效的应用程序生命周期管理。分层构架和联合挂载虚拟机原理需要在Host OS(内核)之上虚拟出一套虚拟硬件,在虚拟硬件之上重新安装操作系统,即为虚拟机操作系统(内核),在该系统之上安装APP,对外提供服务。可见虚拟化对硬件资源的消耗还是比较大,通常在20~30%。而容器概念在于在Host OS之上,提供一套虚拟隔离环境(内核态),在用户空间隔离出进程环境。1.3.2 Docker三个组件 1.3.2.5 镜像一个特殊的文件系统。操作系统分为内核和用户空间,对于Linux来说,内核启动后会挂载root文件系统为其提供用户控件的支持。而Docker镜像,就相当于是一个root文件系统。除了提供容器运行时所需的程序、库、资源、配置等文件外,还包含一些为运行时准备的配置参数。镜像不包含任何动态数据,其内容在构建之后也不会被改变。镜像实际是由多层文件系统联合组成。镜像构建时,会一层一层构建,前一层是后一层的基础。每一层构建完就不会再改变,后一层上的任何改变只发生在当前层。比如:删除前一层文件的操作,实际不是真的删除前一层的文件,而是仅把当前层标记为该文件已删除。分层存储的特征还使得镜像的复用、定制变的更为容易。甚至可以用之前构建好的镜像作为基础层,然后进一步添加新的层,以定制自己所需的内容,构建新的镜像。1.3.2.6 容器镜像(Image)和容器(Container)的关系,就像是面向对象程序设计中的类和实例,镜像是静态的定义,容器是镜像运行时的实体。容器可以被创建、启动、暂停、停止、删除等。容器的实质是进程,但与直接在宿主执行的进程不同,容器进程运行与属于自己独立的命名空间,容器也是分层存储。容器存储层的生命周期跟容器一样,容器消亡时,容器存储层也会消亡,任何保存于容器存储层的信息都会丢失。容器不应该向其存储层内写入任何数据,容器存储层也要保持无状态化。所有的文件写入操作,都应该使用数据卷、或者绑定宿主目录,在这些位置的读写会跳过存储层,直接对宿主发生读写,其性能和稳定性更高。容器消亡后数据卷的数据不会丢失。容器在整个应用程序生命周期工作流中提供以下优点:隔离性、可移植性、灵活性、可伸缩性和可控性。 最重要的优点是可在开发和运营之间提供隔离。1.3.2.7 仓库Docker Registry是一个集中存储、分发镜像的服务。一个Registry可以包含多个仓库(Repository),每个仓库只包含一种软件,但可以包含多个标签(tag,也就是版本),每个标签对应一个镜像。这三个组件的关系如下图,比如有两个仓库,分别是Redis和MySQL。 1.3.3 Docker组成客户端:docker pull build run服务器仓库          镜像image:是个模板,通过模板创建容器服务。通过镜像创建多个容器         容器container:docker通过容器独立运行一个或一组应用,通过镜像来创建的。启动 停止 删除等基本命令                   容器是一个简易的Linux系统         仓库repository:存放镜像的地方1.3.4 Docker架构Client-Server架构:•docker守护进程运行在宿主机上systemctl start docker•daemon进程通过socket从客户端(docker命令)接受命令来运行管理各个容器•容器是一个运行时环境,可以看做是运行中的精简版Linux系统         1.4 docker安装:docker文档:https://docs.docker.com/安装指导:https://docs.docker.com/engine/install/centos/推荐使用阿里云的docker镜像安装:https://blog.csdn.net/lvdingding/article/details/112862396dockerHUB地址: ce社区版,官方推荐ee企业版 hello-world流程底层原理docker是server-client结构的系统,docker的守护进程运行在主机上,通过socketo从客户端访问。dockerserver接受客户端的指令,就会执行docker命令。 1.5 Docker和虚拟机的不同:1.传统虚拟机,虚拟出一套硬件,运行一个完整的操作系统,在这个系统之上安装和运行软件。占用资源大,启动慢。2.容器内的应用直接运行在宿主机的内核上,没有自己的内核,也不需要虚拟硬件,因此容器轻便。3.每个容器互相隔离,每个容器内部都有自己的文件系统,互不影响。DevOps开发运维应用更快的交付和部署传统的交付部署:一堆帮助文档,安装程序docker:打包镜像发布测试一键运行         更便捷的升级和扩缩容         更简单的系统运维,测试环境基本一致         更高效的计算资源利用,docker是内核级的虚拟化,一台服务器上可以运行多个docker实例。         内核的作用在于资源的管理和分配,如内存虚拟化,CPU调用,IO的调度,生产服务,如Nginx等都运行在用户应用空间。1.5.1 Virtual MachinesVM(VMware)在宿主机器、宿主机器操作系统的基础上创建虚拟层、虚拟化的操作系统、虚拟化的仓库,然后再安装应用;1.5.2 Containers容器完全在容器主机的应用程序层中运行。在UserLAnd[1]中,OSs有内核空间,操作系统的核心在其中运行。然后是用户空间,所有与用户活动相关的东西都在这里运行。没有安装操作系统。容器共享主机的内核空间,类似于主机中的一个用户,LXC所实现的隔离性主要是来自kernel的namespace, 其中pid, net, ipc, mnt, uts 等namespace将container的进程, 网络, 消息, 文件系统和hostname 隔离开。但是,cgroup的隔离性要比kvm粒度大,并且很难metric指标。比如,磁盘的IO就很难隔离。导致一个容器的io增大,这个主机都有可能hang。容器实际上就是一个进程。当它在容器内时,感觉就像一台完全独立的机器。我们可以启动新的进程,当监控这些进程时,您将只看到容器内的进程。但是,如果您监控主机进程,仍然能够看到容器中运行的所有内容。 容器共享主机。那么他是如何在同一台机器上运行Ubuntu和CentOS呢? 因为容器实际上共享主机的内核。特定的Linux发行版都构建在同一个内核之上(尽管版本不同)。所有的包管理器、UI之类的东西,以及其他各种软件,都可以在用户空间中运行,这些软件使发行版独一无二,并创造出不同的Linux风格。具有不同发行版的不同容器可以在同一台机器上运行而不会产生冲突。 当涉及到平台设计时,这个内核共享事实还有其他重要的含义。例如,Windows容器将不能在Linux主机上运行。 不可修改 容器本质上是不可变的。 容器操作系统、库、实用程序和应用程序在构建时都是冻结的,在此之后它就不能更改了。所以,不需要以传统的方式更新容器。重新构建和重新部署。虽然有一些缺点,但是在可重复性、简化部署和可靠性方面有很大的提高。 镜像(image) 镜像其实是一个标准的文件包,它表示容器运行时文件系统的状态。这可以发布到注册表,也可以用作父镜像。 大多数镜像将构建在父镜像之上(父镜像通常也构建在另一个镜像像之上)。基本映像没有父镜像的。1.5.3 小结 简而言之,容器化为单个OS上的工作负载隔离提供了标准化的方法,而虚拟化为在一台服务器上安装多个OSs提供了标准化的方法。它们在业界都很突出,在云计算中经常一起使用。 因为容器没有安装完整的操作系统,所以它的重量更轻,因为下载和运行更快,存储更小。下图以尽可能简单的方式说明了上述差异。请注意使用VMs和容器运行相同的两个工作负载的堆栈组合。 如果大家理解了上面描述的容器和vm之间的关键区别,那么第二个图将提供对正在发生的事情的更深入的信息。大家可以清楚地看到这两种技术如何提供工作负载隔离。 记住,堆栈表示逻辑层次结构。我们知道这些容器都在主机操作系统上作为唯一的进程运行,而VM客户操作系统是成熟的操作系统,可以管理它们自己的进程。 现在,让我们看看vm和容器通常是如何一起使用的。假设我们想在云中运行Python Flask应用程序和Java Spring应用程序。下图描述了AWS上可行的状态。  Amazon EC2是Amazon的托管计算服务。这意味着用户不需要担心服务器或管理程序。我们只需选择实例类型(针对不同工作负载的不同特性)并部署VM。(国内的同学们还是使用阿里云吧) 有许多不同的Amazon机器镜像可供选择[3],或者可以创建自己的镜像。因为vm比容器更重。 我们可以在许多不同的服务中共同使用VM镜像。可以将基本操作系统、包更新、一些脚本、监视代理的安装和配置,以及其他操作和安全工具打包到vm中。 通常使用配置管理工具(如Ansible或Chef)来管理工作负载或服务。Chef已经是devops的标准管理工具。 1.6 docker为什么比VM快1.docker的抽象层比虚拟机更少2.docker利用的是宿主机的内核,VM需要guest OSdocker申请容器的时候不需要像虚拟机那样加载一个操作系统内核,避免引导耗时。虚拟机是加载Guest OS,分钟级的docker是利用宿主机的操作系统,省略了这个复杂的过程,秒级。 可见虚拟机对硬件资源的消耗很大,通常在20~30%。 1.7 Docker常用命令docker version版本信息/info 显示docker的系统信息,包括镜像和容器的数量/help 帮助命令官方命令地址:https://docs.docker.com/reference/镜像命令docker imagesdocker searchdocker pulldocker rmidocker rm 容器命令docker inspect 容器IDdocker top 容器ID进入当前运行的容器docker exec -it 容器ID /bin/bash  进入容器后开启一个新终端docker  attach 容器ID             进入容器正在执行的终端,不会执行新进程docker stop/start 容器ID从容器内拷贝内容到宿主机上docker  cp 容器ID:容器内部地址  宿主机地址  思考:在宿主机中提供容器文件的映射地址,实现在宿主机上修改达到容器内部内容的自动修改。---数据卷 docker  run  -it --rm tomcat ##之前都启动是后台启动,容器还可以查到,这个方法为用完就删除容器和镜像1.8 ElasticSearch实验https://www.elastic.co/guide/en/elasticsearch/reference/current/docker.html#docker-cli-run Docker stats:  1.9 PortainerPortainer是docker图形管理工具,提供一个后台面板供开发者使用。访问测试:登录创建用户后选择local本地仓库点击connect之后进入portainer主页  1.10 Docker持续开发工作流  2 Docker镜像详解2.1 镜像详解2.1.1 镜像是什么将应用和环境打包成一个镜像。镜像是轻量级、可执行的独立软件包,打包了运行某个软件(比如tomcat镜像)所需的所有内容,包括:•代码(tomcat代码)•运行时环境(OS、JDK)•依赖库•环境变量•配置文件等镜像底层基础是Union File System(联合文件系统):UnionFS:一种分层、轻量级且高性能的文件系统,支持对文件系统的修改作为一次提交来一层层的叠加,也支持将不同目录挂载到同一虚拟文件系统下。镜像由一层层的文件系统组成,通过分层进行继承。基于基础镜像,可以制作出各种具体的应用镜像。镜像运行时,一次联合加载多个文件系统,根据继承关系进行叠加,最终外部只看到一个文件系统,但拥有了完整的文件和目录结构。 2.1.2 Docker镜像加载原理分层构架,联合挂载。 下载镜像时一层一层下载就是这个概念。所以这也是为什么虚拟机是分钟级,容器是秒级的。 镜像实际有一层层的文件系统组成,即UnionFS。文件系统层级中主要关注bootfs和rootfs“”•bootfs包括BootLoader和kernel(操作系统内核),BootLoader主要是引导加载kernel。同Linux,docker镜像最底层是bootfs。Linux系统启动时,会加载bootfs,然后BootLoader加载kernel(Linux内核)至内存,完成之后内存的使用权由bootfs转移给内核,接着卸载掉bootfs。•rootfs包含了我们熟悉的Linux文件目录结构:/dev/ /proc/ /bin/ /etc/ 等。对于不同的Linux发行版(Ubuntu、centos等),bootfs基本一致(内核相同,都是Linux-kernel),而rootfs会有差别。why一个centos的docker镜像只有200M,而VMware的centos系统镜像几个G?对于一个精简的Linux系统,rootfs可以很小,只需要包括最基本的命令、工具和程序库就OK了。docker容器共用了宿主机的系统内核,只需要提供精简的rootfs就OK,所以docker的os镜像体积可以这么小,因此可以把docker容器看做一个精简的Linux系统。why一个tomcat的docker镜像反而比一个centos的docker镜像大得多每个应用级别的docker镜像,都是源于基础镜像(联合文件系统),类比Java中的Object类,一层层继承而来。 2.2 提交镜像Docker commit 提交容器成为一个新的副本实践如下:    3 Docker数据卷3.1 什么是容器数据卷Docker的核心是把应用和环境打包成镜像,那么数据呢?如果数据保存在容器中,那就无法保证数据的持久化。所以希望容器之间有数据共享功能。通过容器数据卷技术可以将容器中产生的数据,同步到本地。简单说,就是目录挂载,将容器内的目录挂载到宿主机。实现容器数据的持久化和同步操作,也实现了容器间的数据共享。Docker  -v 宿主机目录:容器目录 查看容器卷是否挂载成功,执行命令docker inspect 容器ID3.2 具名和匿名挂载如何确认是具名还是匿名,以及指定路径挂载?3.3 Dockerfile创建 这个卷一定是与外部目录有一个同步目录。该挂载方式为匿名挂载。对应容器外的路径3.4 容器数据卷创建容器数据卷创建目标容器 实现了两个容器数据的同步。多个也是可以实现数据的同步。实现数据在两个mysql中的数据共享  4 Docker dockerfile4.1 基础知识Dockerfile就是构建docker镜像的构建文件,命令参数脚本。 4.2 Dockerfile构建过程Dockerfile是面向开发的,以后发布项目,做镜像,就要编写dockerfile文件,这个文件很简单。Docker镜像逐步成为企业交付的标准,必须掌握。Dockerfile是构建文件,定义了一切步骤,源代码;dockerimages通过dockerfile构建生成的镜像,最终发布和运行产品。Docker容器是镜像运行起来提供服务的。4.3 Dockerfile指令 
总条数:813 到第 页
上滑加载中