Hero Image
修改Mac上brew安装的MySQL配置

#mysql #macos 一般MySQL 8.x安装完在select语句中使用group by时会报错,需要在my.cnf中配置设置sql_model参数。在Linux中,这个文件通常位于/etc目录下,而在Mac上,却不在这里。 在Mac本地安装的测试用的MySQL数据库,安装完成之后需要进行如下设置 设置sql_model 关闭ONLY_FULL_GROUP_BY模式 在sql命令行中查询sql_mode配置 select @@sql_mode; mysql> select @@sql_mode; +-----------------------------------------------------------------------------------------------------------------------+ | @@sql_mode | +-----------------------------------------------------------------------------------------------------------------------+ | ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION | +-----------------------------------------------------------------------------------------------------------------------+ 1 row in set (0.00 sec) 去掉第一项后得到: STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION 使用mysql --help命令获取my.cnf配置文件所在位置 # ... Default options are read from the following files in the given order: /etc/my.cnf /etc/mysql/my.cnf /opt/homebrew/etc/my.cnf ~/.my.cnf The following groups are read: mysql client # ... 我安装的MySQL在/opt/homebrew/etc/my.cnf目录下,添加一行: sql_mode=STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION 重启MySQL,问题解决 mysql.server restart 设置开机启动 cp /opt/homebrew/Cellar/mysql/8.0.27/homebrew.mxcl.mysql.plist ~/Library/LaunchAgents launchctl load -w ~/Library/LaunchAgents/homebrew.

Hero Image
Grafana上监控kubernetes中Pod已用内存不准问题分析

结合上次Golang服务内存增长的分析,近期线上多个服务出现内存持续增长的问题,就这个现象分析一下Prometheus+Grafana的监控问题 #kubernetes #k8s #内存分析 #oom #golang #grafana 问题现象 近期在Grafana上显示生产环境多个服务出现内存持续增长的问题,有Golang的服务,也有JAVA的服务。都是服务重启之后,内存来到一个最低水平, 随着服务运行时间增长,pod的内存占用也随之水涨船高。直到内存占用增长到pod限制的上限附近,内存才出现回收的迹象,并且回收幅度不是特别明显, 但同时又不会出现OOM。 Golang某个服务内存占用情况 JAVA某个服务内存占用情况 简单分析 记一次线上的内存持续增长问题 ↑这个是初次遇到这个问题时候的分析,当时以为是代码写的有漏洞,程序发生了内存泄漏。于是祭出了pprof分析了一顿,结果可想而知,当然是没看出有问题。 现在是多个服务都出现类似问题,那这个情况相对也就比较值得重视了。之前那个服务是因为日志写的比较多,造成磁盘IO比较大。同样的, 近期发现的这几个内存持续不断增长的服务也都是日志量比较大的。 进一步分析 集群日志架构 所有pod中的日志都是写入挂载到/data/log目录的物理机磁盘中,因此所有写日志的操作都会有磁盘IO。日志量越大的pod,磁盘IO相应地也越高。 集群监控 普通pod监控采用了常见的Prometheus+Grafana的方案。 数据源计算方式 监控数据是采集的kubernetes中监控程序cadvisor上报的container_memory_working_set_bytes字段( 表格参照 ) 查看cadvisor源码中setMemoryStats 可知,container_memory_working_set_bytes字段是cgroup memory.usage_in_bytes(RSS + Cache)与memory.stat total_inactive_file二者的差值 func setMemoryStats(s *cgroups.Stats, ret *info.ContainerStats) { // ... // ... inactiveFileKeyName := "total_inactive_file" if cgroups.IsCgroup2UnifiedMode() { inactiveFileKeyName = "inactive_file" } workingSet := ret.Memory.Usage if v, ok := s.MemoryStats.Stats[inactiveFileKeyName]; ok { if workingSet < v { workingSet = 0 } else { workingSet -= v } } ret.

Hero Image
记一次线上的内存持续增长问题

#golang #oom #内存分析 #grafana #kubernetes #k8s 问题现象 前些天从Grafana上看到某一个pod内存涨上去就再没下来(从9/1~9/2之间的一个时间开始),并且看这个趋势涨上去就没有下来的意思。中间有几次pod重新发布 才导致内存恢复到一个比较低的水平,但内存依旧持续上涨。 初步分析 初步推测大概率与日志有关,此次发版改动了日志输出格式,以及修改了日志没有写入磁盘的问题。 先把服务稳住 由于清楚问题的大致方向,先将服务中几个打印log比较频繁的位置注释掉,在9/3~9/4之间的一个位置重新发布。从之后的趋势上可以看出,注释掉几个打印日志的 地方之后,内存增长速度明显放缓。 至此,基本可以确认内存增长与日志相关。 问题排查 猜测一 回头又捋了几遍代码,也没发现什么端倪。 于是祭出pprof抓了一下内存分析了一通,依旧无果。 可以看出,内存占用并没有多高。 猜测二 在 Go1.12 以前,Go Runtime在Linux上使用的是MADV_DONTNEED策略,可以让RSS下降的比较快,就是效率差点。 在 Go1.12 及以后,Go Runtime专门针对其进行了优化,使用了更为高效的MADV_FREE策略。但这样子所带来的副作用就是RSS不会立刻下降, 要等到系统有内存压力了才会释放占用,RSS才会下降。 查看容器的 Linux 内核版本: # 查看命令 uname -a 课件容器版本为3.10.0,但MADV_FREE的策略改变,需要Linux内核在4.5及以上(详细可见go/issues/23687 ), 因此可以排除。 猜想三 通过top命令可以通过可以查看容器中程序的内存占用VSZ为711,无法查看RSS,关于RSS和VSZ的区别,可以参考RSS和VSZ 容器内存判定是通过container_memory_working_set_bytes,而container_memory_working_set_bytes是由cadvisor提供的。 原因 从cadvisor/issues/638 可得知container_memory_working_set_bytes指标的组 成实际上是RSS + Cache。而Cache高的情况,常见于进程有大量文件IO,占用Cache可能就会比较高,猜测也与Go版本、Linux 内核版本的Cache释放、回收方式有较大关系。 只要是涉及有大量文件IO的服务,基本上是这个问题的老常客了,写这类服务基本写一个中一个,因为这是一个混合问题,像其它单纯操作为主的业务服务就很 “正常”,不会出现内存居高不下。 没多久看到烤鱼佬的一篇文章,与这个情况类似,他的解决办法也就是写了个脚本,“手动"HPA(其实也就是自动重启)。 总结 虽然这问题时间跨度比较长,整体来讲都是阶段性排查,本质上可以说是对Kubernetes的不熟悉有关。但因为内存居高不下的可能性有很多种,要一个个排查。