July 26, 2019
docker exec 命令原理
"\u003cp\u003e我们经常使用 docker exec 命令进入到一个容器里进行一些操作,那么这个命令是如果进入到容器里的呢?想必大家都知道用到了Namespace来实现,但至于底层实现原理是什么,想必都不是特别清楚吧。\u003c/p\u003e\n\u003cp\u003e我们知道容器的本质其实就是一个进程,每个进程都有一个Pid,至于容器的Pid值可以通过 docker inspect container_id 来查看,我们这里是一个Python应用容器,我们看一下他的 Pid值\u003c/p\u003e\n\u003cpre tabindex=\"0\"\u003e\u003ccode\u003edocker inspect --format \u0026#39;{{ .State.Pid }}\u0026#39; 4ddf4638572d\n25686\n\u003c/code\u003e\u003c/pre\u003e\u003cp\u003e而每个进程都有自己的Namespace,你可以通过查看宿主机的 proc 文件,看到这个 25686 进程的所有 Namespace 对应的文件\u003c/p\u003e\n\u003cpre tabindex=\"0\"\u003e\u003ccode\u003els -l /proc/25686/ns\ntotal 0\nlrwxrwxrwx 1 root root 0 Aug 13 14:05 cgroup -\u0026gt; cgroup:[4026531835]\nlrwxrwxrwx 1 root root 0 Aug 13 14:05 ipc …\u003c/code\u003e\u003c/pre\u003e"
July 26, 2019
docker中的命名空间
"\u003cp\u003eNamespace 的作用是“隔离”,它让应用进程只能看到该Namespace 内的“世界”;而 Cgroups 的作用是“限制”,它给这个“世界”围上了一圈看不见的墙。\u003c/p\u003e\n\u003cp\u003e命名空间是 Linux 内核一个强大的特性。每个容器都有自己单独的命名空间,运行在其中的应用都像是在独立的操作系统中运行一样。命名空间保证了容器之间彼此互不影响。\u003c/p\u003e\n\u003cp\u003e在docker中一共有以下几个命名空间,每个Namespace的发挥着不同的作用。\u003cimg src=\"https://blogstatic.haohtml.com//uploads/2023/09/docker-namespace.png\" alt=\"\"\u003e\u003c/p\u003e\n\u003ch3 id=\"pid-命名空间\"\u003epid 命名空间\u003c/h3\u003e\n\u003cp\u003e不同用户的进程就是通过 pid 命名空间隔离开的,且不同命名空间中可以有相同 pid。在同一个Namespace中只能看到当前命名空间的进程。所有的 LXC 进程在 Docker 中的父进程为Docker进程,每个 LXC 进程具有不同的命名空间。同时由于允许嵌套,因此可以很方便的实现嵌套的 Docker 容器。\u003c/p\u003e\n\u003ch3 id=\"net-命名空间\"\u003enet 命名空间\u003c/h3\u003e\n\u003cp\u003e有了 pid 命名空间, 每个命名空间中的 pid 能够相互隔离,但是网络端口还是共享 host 的端口。网络隔离是通过 net 命名空间实现的, 每个 net 命名空间有独立的 网络设备, IP 地址, 路由表, …\u003c/p\u003e"
July 13, 2019
docker容器调试利器nicolaka/netshoot
"\u003ch2 id=\"背景\"\u003e背景\u003c/h2\u003e\n\u003cp\u003e在日常工作中,我们一般会将容器进行精简,将其大小压缩到最小,以此来提高容器部署效率,参考\u003ca href=\"https://mp.weixin.qq.com/s/S1Ib08SpQbf1SCbCutUoqQ\"\u003e小米云技术 – Docker最佳实践:5个方法精简镜像\u003c/a\u003e。但有一个比较尴尬的问题就是对容器排障,由于容器里没有了我们日常工作中用到许多排障命令,如top、ps、netstat等,所以想排除故障的话,常用的做法是安装对应的命令,如果容器过多的话,再这样搞就有些麻烦了,特别是在一些安装包源速度很慢的情况。\u003c/p\u003e\n\u003ch2 id=\"解决方案\"\u003e解决方案\u003c/h2\u003e\n\u003cp\u003e今天发现一篇文章(\u003ca href=\"http://www.dockone.io/article/9032\"\u003e简化 Pod 故障诊断:kubectl-debug 介绍\u003c/a\u003e)介绍针对此类问题的解决方案的,这里介绍的是一个叫做 \u003ccode\u003ekubectl-debug\u003c/code\u003e 的命令,由国内知名的PingCAP公司出品的,主要用在k8s环境中的。我们知道容器里主要两大技术,一个是用\u003cstrong\u003ecgroup来实现容器资源的限制\u003c/strong\u003e,一个是用\u003cstrong\u003eNamespace来实现容器的资源隔离的\u003c/strong\u003e)。(kubectl-debug 命令是基于一个工具包() 来实现的,其原理是利用将一个工具包容器添加到目标容器所在的Pod里,实现和目标容器的Network Namespace一致,从而达到对新旧容器进程的相互可见性,这样我们就可以直接在目标容器里 …\u003c/p\u003e"
July 12, 2019
基于docker环境实现Elasticsearch 集群环境
"\u003cp\u003e最近搭建了es集群的时候,现在需要测试添加一个新的数据节点,项目是使用docker-compose命令来搭建的。\u003c/p\u003e\n\u003cp\u003e以下基于最新版本 es7.2.0进行, 配置文件目录为 es, 所以docker 在创建网络的时候,网络名称会以 es_ 前缀开始,如本例中我们在docker-composer.yaml文件中指定了网络名称为esnet,但docker生成的实例名称为 es_esnet,至于网络相关的信息可以通过 \u003ccode\u003edocker network --help\u003c/code\u003e 查看。\u003c/p\u003e\n\u003ch2 id=\"搭建es集群\"\u003e搭建es集群\u003c/h2\u003e\n\u003cp\u003e// docker-compose.yaml 集群配置文件\u003c/p\u003e\n\u003cpre tabindex=\"0\"\u003e\u003ccode\u003eversion: \u0026#39;2.2\u0026#39;\nservices:\n es01:\n image: docker.elastic.co/elasticsearch/elasticsearch:7.2.0\n container_name: es01\n environment:\n - node.name=es01\n - node.master=true\n - node.data=true\n - …\u003c/code\u003e\u003c/pre\u003e"
July 11, 2019
golang内存对齐(进阶必看)
"\u003cp\u003e先看一个结构体\u003c/p\u003e\n\u003cpre tabindex=\"0\"\u003e\u003ccode\u003e// 写法一\ntype T1 struct {\n\ta int8\n\tb int64\n\tc int16\n}\n\n// 写法二\ntype T2 struct {\n\ta int8\n\tc int16\n\tb int64\n}\n\u003c/code\u003e\u003c/pre\u003e\u003cp\u003e对于这两个结构体,都有a、b、c三个定义完全一样的字段,只是在定义结构体的时候字段顺序不一样而已,那么两种写法有什么影响吗?\u003c/p\u003e\n\u003cp\u003e对于新手来说,感觉着没有什么区别的,只是一个书写顺序不同而已,但对于go编译器来说,则有着很大的区别,特别是在不同架构上(32位/64位)的编译器,在一定程度上对内存的使用大小和执行效率有着一定的不同。这里的主要知识点就是golang语言中的内存对齐概念(alignment guarantee),\u003c/p\u003e\n\u003ch2 id=\"类型的尺寸和结构体字节填充structure-padding\"\u003e类型的尺寸和结构体字节填充(structure padding)\u003c/h2\u003e\n\u003cp\u003eGo白皮书只对以下种类的类型的尺寸进行了\u003ca href=\"https://golang.google.cn/ref/spec#Size_and_alignment_guarantees\"\u003e明确规定\u003c/a\u003e。\u003c/p\u003e\n\u003cpre tabindex=\"0\"\u003e\u003ccode\u003e类型种类 尺寸(字节数)\n------ ------\nbyte, uint8, int8 1\nuint16, int16 2 …\u003c/code\u003e\u003c/pre\u003e"
July 10, 2019
kafka常用术语
"\u003cp\u003e官方网站:,中文: \u003ca href=\"http://kafka.apachecn.org/\"\u003ehttp://kafka.apachecn.org/\u003c/a\u003e\u003c/p\u003e\n\u003cp\u003e注意它和其它消息系统(消息队列)在\u003cstrong\u003e定义\u003c/strong\u003e上的区别,以便更好的理解它的应用场景。\u003cstrong\u003eApache Kafka 是一款分布式流处理平台(Distributed Streaming Platform)\u003c/strong\u003e。\u003c/p\u003e\n\u003ch2 id=\"术语\"\u003e术语\u003c/h2\u003e\n\u003cp\u003e消息:Record。消息实体,是通信的基本单位。\n主题:Topic。主题是承载消息的\u003cstrong\u003e逻辑容器\u003c/strong\u003e,在实际使用中多用来区分具体的业务。\n分区:Partition。一个\u003cstrong\u003e有序不变\u003c/strong\u003e的消息序列。每个主题Topic下可以有多个分区。\n消息位移:Offset。表示分区中每条消息的位置信息,是一个\u003cstrong\u003e单调递增\u003c/strong\u003e且不变的值。\n缓存代理,Broker。Kafka集群中的一台或多台服务器统称broker。\n副本:Replica。Kafka 中同一条消息能够被拷贝到多个地方以提供数据冗余,这些地方就是所谓的副本。\u003cstrong\u003e\u003cem\u003e副本还分为领导者副本和追随者副本\u003c/em\u003e\u003c/strong\u003e,各自有不同的角色划分。副本是在分区层级下的,即每个分区可配置多个副本实现高可用。\n生产者:Producer。向主题发布新消息的应用程序。\n消费者:Consumer。从主题订阅新消息的应用程序。\n消费者位 …\u003c/p\u003e"
July 3, 2019
ES集群的高可用性之节点
"\u003cp\u003e为了防止ES集群中单点问题,一般都需要对集群节点做高可用性,当发生单点问题时,也可以向外正常提供服务。这里主要记录一下节点的加入、离开和主节点选举。\u003c/p\u003e\n\u003cp\u003e集群安装教程请参考:\u003c/p\u003e\n\u003ch2 id=\"节点角色\"\u003e节点角色\u003c/h2\u003e\n\u003cp\u003e集群是由多个节点组成的,每个节点都扮演着不同的角色,一般常用的有 Master、Data 和 client。节点角色介绍:\u003c/p\u003e\n\u003cp\u003e节点角色配置参数:\nnode.master: true\nnode.data: false\nnode.ingest: false\u003c/p\u003e\n\u003cp\u003e在一个集群中,可以通过 查看到每个节点在集群中扮演的角色,一个节点可同时拥有多个角色,如值MDI,同时也是每个节点的默认值,其中的 Ingest 节点也称作\u003cstrong\u003e预处理节点\u003c/strong\u003e,不过在生产环境中一般将master 和 data节点分开的。所有节点默认都是支持 Ingest 操作的。节点组合参考:\u003c/p\u003e\n\u003ch2 id=\"新节点的加入\"\u003e新节点的加入\u003c/h2\u003e\n\u003cp\u003e随着数量大的增加,有时候我们不得进行机器的扩容,这时间就需要加入一些新的机器节点,用来提高访问速度。\u003c/p\u003e\n\u003cp\u003e当一个新节点加入的时候,它通过读取 \u003ccode\u003ediscovery.zen.ping.unicast.hosts\u003c/code\u003e 配置的节点获取集群状态,然后找到 \u003ccode\u003emaster\u003c/code\u003e 节点,并向 …\u003c/p\u003e"
July 2, 2019
docker容器 Exited (137)错误代码
"\u003cp\u003e最近要搭建es集群,由于刚接触es不久,直接使用的docker构建,发现当用两个容器搭建好集群时,再添加新的es容器节点时,总是出现其它容器被kill的现象,查看容器日志未发现任何错误信息,导致一段时间非常的迷茫。\u003c/p\u003e\n\u003cp\u003e起始认为是配置不当引起了,于是一直在配置这方面找问题,网上的有些教程是直接在物理机器上或者虚拟机上进行部署,而自己的环境是docker, 通过 docker-compose 来部署的,\b环境有些差异。\u003c/p\u003e\n\u003cp\u003e有网友提醒有可能是由 OOM 引起的问题,因为代码是137, 使用命令 “\u003ccode\u003edocker inspect 容器ID\u003c/code\u003e” 查看了一下容器, status列显示”\u003ccode\u003eOOMKilled\u0026quot;: false\u003c/code\u003e” ,所以从这里查看的话,并非是 OOM 引起的,起初个人分析容器的启动过程,是在启动一个容器时,dockerd应该先检查内存是否足够,如果不足够的话,则启动新窗口失败才对,而不是先将已存在的窗口killed,再去启动新容器,所以仍将OOM的原因排除掉了。\u003c/p\u003e\n\u003cp\u003e后来\b发现一篇文章 介绍到这个和 docker for mac 分配的内存大小有关系,试着将给 docker 分配的内存调整 …\u003c/p\u003e"
July 1, 2019
mac手动停止 php-fpm 服务
"\u003cp\u003e由于要安装一个docker服务,对外提供端口用的是9000, 和php-fpm的监听端口冲突,所以需要先停止一下php-fpm服务。\u003c/p\u003e\n\u003cp\u003e多次执行\u003c/p\u003e\n\u003cp\u003e\u003ccode\u003esudo killall php-fpm\u003c/code\u003e\u003c/p\u003e\n\u003cp\u003e发现过一会php-fpm会自动启动,就算一个一个的进程kill -9 也一样的效果。经过分析这个应该是和php-fpm配置文件 ~/Library/LaunchAgents/[email protected] 有关。\u003c/p\u003e\n\u003cp\u003e我们知道 ~/Library/LaunchAgents 针对当前用户的启动项目录,针对这个项目里的一些配置服务有一个 launchctl 命令可以操作,其中有几个命令我们需要知道他的意思\u003c/p\u003e\n\u003cpre tabindex=\"0\"\u003e\u003ccode\u003elaunchctl load 启动plist运行\nlaunchctl unload 卸载\nlaunchctl list 查看所有启动任务\n\u003c/code\u003e\u003c/pre\u003e\u003cp\u003e默认当用户登录后,mac系统会对当前目录 ~/Library/LaunchAgents 里的每个配置服务文件自动执行launchctl load 命令。如果我们想停止一个服务的话,则需要执行 launchctl unload 命令即可。\u003c/p\u003e\n\u003cp\u003e`$ …\u003c/p\u003e"
June 26, 2019
MySQL8.0中的几项新特性(整理)
"\u003cp\u003e\u003ca href=\"https://mp.weixin.qq.com/s/DHnGZroN36aC46Erzq6TWg\"\u003e新特新解读 | MySQL 8.0 对 count(*)的优化\u003c/a\u003e \u003ca href=\"https://mp.weixin.qq.com/s/ViGU5i5XlFjDTath_dh6pg\"\u003e新特性解读 | MySQL 8.0 正则替换\u003c/a\u003e \u003ca href=\"https://mp.weixin.qq.com/s/EOJ_jIhW07ifiYbpXs0lcQ\"\u003e新特性解读 | MySQL 8.0 资源组\u003c/a\u003e \u003ca href=\"https://mp.weixin.qq.com/s/4oUIW5_vWzWYAx_oMTwHOw\"\u003e新特性解读 | MySQL 8.0 Temptable 引擎介绍\u003c/a\u003e\u003c/p\u003e\n\u003cp\u003e\u003ca href=\"https://mp.weixin.qq.com/s/Ocl2FTQ847Pwxtjp8N7L6w\"\u003e新特性解读 | MySQL 8.0 窗口函数详解\u003c/a\u003e\u003c/p\u003e\n\u003cp\u003e\u003ca href=\"https://mp.weixin.qq.com/s/f-Za9y-6VsAs5VukyftqRA\"\u003e新特性解读 | MySQL 8.0 json到表的转换\u003c/a\u003e\u003c/p\u003e\n\u003cp\u003e\u003ca href=\"https://mp.weixin.qq.com/s/ZJ9slZVAc5k1BYsX0id2Mg\"\u003e新特性解读 | MySQL 8.0.16 在组复制中启用成员自动重新加入\u003c/a\u003e\u003c/p\u003e\n\u003cp\u003e\u003ca href=\"https://mp.weixin.qq.com/s/0NsfuTAVxCMRBz-NMQxA3Q\"\u003e新特性解读 | MySQL 8.0 直方图\u003c/a\u003e\u003c/p\u003e\n\u003cp\u003e\u003ca href=\"https://mp.weixin.qq.com/s/aCe3UYnEnqGSE90bEFxxMg\"\u003e新特性解读 | MySQL 8.0 索引特性1-函数索引\u003c/a\u003e\u003c/p\u003e\n\u003cp\u003e\u003ca href=\"https://mp.weixin.qq.com/s/J7LfZjhJak_rQ_Ft2sFmVQ\"\u003e新特性解读 | MySQL 8.0 索引特性2-索引跳跃扫描\u003c/a\u003e\u003c/p\u003e\n\u003cp\u003e\u003ca href=\"https://mp.weixin.qq.com/s/_zTybsp6NQa_gbhGmCySvA\"\u003e新特性解读 | MySQL 8.0 索引特性3 -倒序索引\u003c/a\u003e\u003c/p\u003e\n\u003cp\u003e\u003ca href=\"https://mp.weixin.qq.com/s/mdpZz9-Em1tQupK6ajYJJg\"\u003e新特性解读 | MySQL 8.0 索引特性4-不可见索引\u003c/a\u003e\u003c/p\u003e\n\u003cp\u003e\u003ca href=\"https://mp.weixin.qq.com/s/GOw9Vb9iRV1r1IpvkTyHwQ\"\u003e新特性解读 | MySQL 8.0.16 组复制通讯协议的设置\u003c/a\u003e\u003c/p\u003e\n\u003cp\u003e\u003ca href=\"https://mp.weixin.qq.com/s/U40BPB3N9jBx3NIKUhQXxA\"\u003e新特性解读 | MySQL 8.0.16 组复制新功能:消息碎片化\u003c/a\u003e\u003c/p\u003e"
June 20, 2019
一文读懂 MySQL 的隔离级别和锁的关系
"\u003cp\u003eMySQL 中的隔离四种隔离级别与锁的关系一直挺模糊的,看了好多文章感觉着都不是很好理解,今天在“\u003ca href=\"https://mp.weixin.qq.com/s/DhMy6fsdlFj3dGqRE_0JMg\"\u003e爱可生开源社区\u003c/a\u003e”看到一篇文章,感觉着挺容易理解的。\u003c/p\u003e\n\u003cblockquote\u003e\n\u003cp\u003e\u003ccode\u003eREAD UNCOMMITTED 未提交读,可以读取未提交的数据。\u003c/code\u003e\u003c/p\u003e\n\u003cp\u003e\u003ccode\u003eREAD COMMITTED 已提交读,对于锁定读(select with for update 或者 for share)、update 和 delete 语句, InnoDB 仅锁定索引记录,而不锁定它们之间的间隙,因此允许在锁定的记录旁边自由插入新记录。\u003c/code\u003e Gap locking 仅用于外键约束检查和重复键检查。\u003c/p\u003e\n\u003cp\u003e\u003ccode\u003eREPEATABLE READ 可重复读,事务中的一致性读取读取的是事务第一次读取所建立的快照。\u003c/code\u003e\u003c/p\u003e\n\u003cp\u003e\u003ccode\u003eSERIALIZABLE 序列化\u003c/code\u003e\u003c/p\u003e\u003c/blockquote\u003e\n\u003cp\u003e文中主要对 RR 和 RC 两种常用的隔离级别做了不同情况的说明,对于 \u003ccode\u003eSERIALIZABLE 序列化\u003c/code\u003e 和 READ UNCOMMITTED 未提交读,由于很好理解所以未在文中体现。**对于 RR 和 RC 主要区别是 RR 存在 Gap Lock间隙锁,而RC则 …\u003c/p\u003e"
April 9, 2019
MySQL5.7中Undo回收收缩相关参数
"\u003cp\u003e在MySQL5.7以前,ibdata1文件会逐渐增大( \u003ca href=\"https://dev.mysql.com/doc/refman/5.7/en/glossary.html#glos_ibdata_file\"\u003eibdata1文件包含哪些信息?\u003c/a\u003e),非常占用系统空间,特别是一些云数据来说,磁盘非常的贵,想要回收空间,只能进行一次导出和导入操作,来重新生成undo 表空间,从MySQL5.7开始,有了在线回收undo表空间的功能,主要由以下几个参数设置。\u003c/p\u003e\n\u003cp\u003e\u003cstrong\u003einnodb_undo_directory = .\u003c/strong\u003e\n为undo文件存储路径。如果没有指定默认值(NULL),则undo表空间则存放到mysql的data目录里(datadir选项)。配置此项可以用undo从ibdata文件里分离出来。单独存储。\u003c/p\u003e\n\u003cp\u003e\u003cstrong\u003einnodb_undo_logs = 128\u003c/strong\u003e\n(默认值 128)undo rollback segment 回滚段个数,为 innodb_rollback_segments 参数选项的别名,最大值为128,其中32个为使用临时表空间 ibtmp1 保留,1个为系统表空间使用,剩余的95个为 undo tablespaces 使用。\n当 innodb_rollback_segments\u0026lt;=32的时候,系统将自动分配1个rollback …\u003c/p\u003e"
March 23, 2019
goroutine和线程区别
"\u003cp\u003e从调度上看,goroutine的调度开销远远小于线程调度开销。\u003c/p\u003e\n\u003cp\u003e\u003cstrong\u003eOS的线程由OS内核调度,每隔几毫秒,一个硬件时钟中断发到CPU,CPU调用一个调度器内核函数\u003c/strong\u003e。这个函数暂停当前正在运行的线程,把他的寄存器信息保存到内存中(暂时保存线程状态),查看线程列表并决定接下来运行哪一个线程,再从内存中恢复线程的注册表信息,最后继续执行选中的线程。这种线程切换需要一个完整的上下文切换:即保存一个线程的状态到内存,再恢复另外一个线程的状态,最后更新调度器的数据结构。某种意义上,这种操作还是很慢的。\u003cimg src=\"https://blogstatic.haohtml.com//uploads/2023/09/go_scheduler.png\" alt=\"\"\u003eOS 线程调度器\u003c/p\u003e\n\u003cp\u003e\u003cstrong\u003eGo运行的时候包涵一个自己的调度器\u003c/strong\u003e,这个调度器使用一个称为一个M:N调度技术,m个goroutine到n个os线程(可以用GOMAXPROCS来控制n的数量),\u003cstrong\u003eGo的调度器不是由硬件时钟来定期触发的,而是由特定的go语言结构来触发的\u003c/strong\u003e,他不需要切换到内核语境,所以调度一个goroutine比调度一个线程的成本低很多。\u003c/p\u003e\n\u003cp\u003e从栈空间上,goroutine的栈空间更加动态灵活。\u003c/p\u003e\n\u003cp\u003e每个OS的线程都有一个固定大小的栈内存,通常是2MB,栈内存用于保存在其他函数调用期间哪些正在执行或者临时暂停的函数的局部 …\u003c/p\u003e"
February 21, 2019
理解MySQL中的MDL锁
"\u003cul\u003e\n\u003cli\u003e\u003ca href=\"https://cloud.tencent.com/developer/article/1006514\"\u003ehttps://cloud.tencent.com/developer/article/1006514\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"https://yq.aliyun.com/articles/27667\"\u003ehttps://yq.aliyun.com/articles/27667\u003c/a\u003e\u003c/li\u003e\n\u003c/ul\u003e"
January 26, 2019
docker中将MySQL运行在容器中失败提示“ InnoDB : Error 22 with aio_write”的解决办法
"\u003cp\u003e今天利用docker容器创建mysql8.0的时候(window系统),指定了本地宿主机器的一个目录为容器mysql的datadir目录,发现创建失败了。\u003c/p\u003e\n\u003cp\u003e创建命令:\u003c/p\u003e\n\u003cpre tabindex=\"0\"\u003e\u003ccode\u003e$ docker run -d --name mysql81 -v /e/container/mysql/mysql81/datadir:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 -p 33081:3306 mysql\n\u003c/code\u003e\u003c/pre\u003e\u003cp\u003e错误提示:\u003c/p\u003e\n\u003cpre tabindex=\"0\"\u003e\u003ccode\u003e$ docker logs mysql81\n2019-01-26T03:05:42.567230Z 0 [Warning] [MY-011070] [Server] \u0026#39;Disabling symbolic links using --skip-symbolic-links (or equivalent) is the default. Consider not using this option as it\u0026#39; is deprecated and will be removed in a future release. …\u003c/code\u003e\u003c/pre\u003e"