ThinkPad X270 上安装 Debian

最近因为一些原因将办公操作系统由 Windows 改为 Linux。 由于已经在 Debian 9下开发了小半年时间,索性还是以Debian 9 作为办公系统。接下来会有一系列的相关文章记录这个过程。这篇文章记录我在笔记本 Thinkpad X270 上安装 Debian 9 的过程。其他版本的大同小异。

注意安装时要使用网线安装,默认没有 wifi 驱动,需要后面手动安装。另外一开始也没有触摸板的驱动,所以使用ui界面安装时候需要把鼠标插上。

一、USB烧录系统

  1. 官网上获取最新镜像地址:https://cdimage.debian.org/debian-cd/current/amd64/bt-dvd/

  2. 准备一个空的U盘用来刻录 debian 的系统,8G就足够用了。

  3. 推荐使用 rufus 烧录镜像。

    [rufus screenshot]

二、笔记本BIOS设置

这里简单涉及笔记本 UEFI 、Legacy UEFI+Legacy启动的区别了。

1. uefi 和legacy 是两种不同的引导方式

uefi是新式的BIOS,legacy是传统BIOS。在UEFI模式下安装的系统,只能用UEFI模式引导;

同理,如果在Legacy模式下安装的系统,也只能在legacy模式下进系统。

  • uefi只支持64为系统且磁盘分区必须为gpt模式,
  • 传统BIOS使用Int 13中断读取磁盘,每次只能读64KB,
  • UEFI每次可以读1MB,载入更快。

在目前的系统运行方式中,win8/win10 基于UEFI方式启动,其余均为Legacy方式启动。

因此,我们需要修改笔记本默认引导方式由 UEFI 改为 Legacy。

2. 进入BIOS设置

  1. 按电脑电源按钮(或重启)

  2. 不同电脑进入BIOS的快捷键不同,通常为F1、F2、DEL、ESC等,根据提示操作把。针对 X270,开机狂按 Enter 就可以选择进入 BIOS了。

  3. 关闭安全启动

    对于有些主板来说,只有 把Secure Boot Control 设置为 Disable 的时候才能把 Launch CSM选项设置为Legacy。对于 Thinkpad X270 来说是如此。

    image-20210601140120615

    设置为 disable。只有关闭了安全登陆,才可以更改 BIOS 引导为 Legacy

    image-20210601140137095

    修改 Legacy 为优先启动顺序。

    image-20210601140734700

  4. 最后可以修改加载磁盘顺序,也可以在启动的时候狂按 Enter 键后手动选择。

    image-20210601140624396

3. 安装debian

这一块没有什么特别好说的,一路按照提示安装就可以了。

4. 安装wifi驱动

关于 Debian 在不同硬件上的安装,其实可以参考官方 wiki 中的介绍:https://wiki.debian.org/InstallingDebianOn/Thinkpad/X270/sid,官方已经对硬件进行了测试,可以细看 wifi 相关的描述, Only works with a non-free driver and or firmware

image-20210601141225593

往下翻:

image-20210601141622011

关键字出来了: iwlwifi –Debian Wiki,英特尔 Wi-Fi 设备的专有驱动程序。

/etc/apt/source.list 里追加:

# Debian 9 "Stretch"
deb http://httpredir.debian.org/debian/ stretch main contrib non-free

安装:

apt update
apt install firmware-iwlwifi
reboot

完成。

参考资料


记一次docker问题定位 - 孙庚泽

转自:https://mp.weixin.qq.com/s/Gc0cEZYlazzyAeS-9vsGUA

图片

性能测试发现业务进程运行在容器中比业务进程运行在宿主机上吞吐量下降了 100 倍,这让周一显得更加阴暗。

背景

最近参与的项目是基于 OpenStack 提供容器管理能力,丰富公司 IaaS 平台的能力。日常主要工作就是在开源的 novadocker 项目(开源社区已停止开发)基础上进行增强,与公司的其他业务组件进行对接等。

周末给下游部门的 IaaS 平台进行了一次升级,主要升级了底层操作系统,基本用例跑通过,没出现什么问题,皆大欢喜。

结果周一一到公司就传来噩耗,性能测试发现业务进程运行在容器中比业务进程运行在宿主机上吞吐量下降了 100 倍,这让周一显得更加阴暗。

周一

先找下游了解了下业务模型,他们说已经把业务模型最简化了,当前的模式是:业务进程运行在容器中,通过与主机共享 IPC namespace 的方式来使用共享内存与宿主机上的 Daemon 进程进行通信,整个过程不涉及磁盘读写、网络交互等。

撸起袖子开始干,定位第一步,当然是找瓶颈了,分析下到底问题出在哪。

top

用到的第一个命令自然是 top,top 是 linux 里一个非常强大的命令,通过它基本上能看到系统中的所有指标。

图片

上面是 top 命令运行时的一个示意图,比较重要的指标都已经标了出来:

1 处表示系统负载,它表示当前正在等待被 cpu 调度的进程数量,这个值小于系统 vcpu 数(超线程数)的时候是比较正常的,一旦大于 vcpu 数,则说明并发运行的进程太多了,有进程迟迟得不到 cpu 时间。这种情况给用户的直观感受就是敲任何命令都卡。

2 处表示当前系统的总进程数,通常该值过大的时候就会导致 load average 过大。

3 处表示 cpu 的空闲时间,可以反应 cpu 的繁忙程度,该值较高时表示系统 cpu 处于比较清闲的状态,如果该值较低,则说明系统的 cpu 比较繁忙。需要注意的是,有些时候该值比较高,表示 cpu 比较清闲,但是 load average 依然比较高,这种情况很可能就是因为进程数太多,进程切换占用了大量的 cpu 时间,从而挤占了业务运行需要使用的 cpu 时间。

4 处表示进程 IO 等待的时间,该值较高时表示系统的瓶颈可能出现在磁盘和网络。

5 处表示系统的剩余内存,反应了系统的内存使用情况。

6 处表示单个进程的 cpu 和内存使用情况。

使用 top 命令查看了下系统情况,发现一切正常。load average 也不高,task 也不多,cpu 和内存都还很空闲,就连 IO 等待时间都很低,也没有哪个进程的 cpu 和内存使用率偏高,一切都很和谐,没有瓶颈!

当然,没有瓶颈是不可能的。由于我们的容器都是绑核的,所以很有可能是分配给容器的那些核是处于繁忙状态,而由于总核数较多,将 cpu 的使用率给拉了下来。于是又按下了“1”键,切换到详细模式下:

图片

在这种模式下,可以看到每个 vcpu 的使用情况。一切依然很和谐,诡异的和谐。

看来从 cpu 这块是看不出来什么了,那就继续看看是不是磁盘搞的鬼吧。

iostate

iostate 命令是用来查看磁盘使用情况的一个命令,经验告诉我们,磁盘和网络已经成为影响性能的最大嫌疑犯。

图片

使用 iostate 工具时,通常只用关注最后一行(%util)即可,它反映了磁盘的繁忙程度。虽然下游部门已经说了他们跑的用例是一个纯内存的场景,不涉及磁盘读写。但是客户的话信得住,母猪也能上树,我还是要跑一下 iostate,看下磁盘情况怎么样。结果,依旧很和谐,磁盘使用率基本为零。

后面还尝试了观察网络指标,发现确实也没有网络吞吐,完了,看来问题没那么简单。

周二

虽然周一看似白忙活了一天,但是也得到了一个重要结论:这个问题不简单!不过简单的在资源层面时分析不出来啥了,得寄出性能分析的大杀器——perf 了。

perf+ 火焰图

perf 是 linux 下一个非常强大的性能分析工具,通过它可以分析出进程运行过程中的主要时间都花在了哪些地方。

之前没太使用过 perf,因此刚开始进行分析,就自然而然地直接使用上了 perf+ 火焰图这种最常见的组合:

  1. 安装 perf。

    yum install perf

  2. 下载火焰图工具。

    git clone https://github.com/brendangregg/FlameGraph.git

  3. 采样。

    perf record -e cpu-clock -g -p 1572(业务进程 id)

    一段时间(通常 20s 足够)之后 ctrl+c,结束采样。

  4. 用 perf script 工具对 perf.data 进行解析。

    perf script -i perf.data &> perf.unfold。

    PS:如果在容器中运行的程序有较多的依赖,则该命令解析出来的符号中可能会有较多的“Unregistered symbol…”错误,此时需要通过--symfs参数指定容器的rootfs位置来解决该问题。获取容器rootfs的方法根据 docker 的 storagedriver 的不同而有所不同,如果是device mapper类型,则可以通过 dockerinspect 找到容器的rootfs所在位置,如果是overlay类型,则需要通过 dockerexport 命令将该容器的rootfs导出来,如果是富容器的话,一般都有外置的rootfs,直接使用即可。

  5. 将 perf.unfold 中的符号进行折叠。

    ./stackcollapse-perf.pl perf.unfold &> perf.folded

  6. 最后生成 svg 图。

    /flamegraph.pl perf.folded > perf.svg

最后就能得到像下面这种样子的漂亮图片。通常情况下,如果程序中有一些函数占用了大量的 CPU 时间,则会在图片中以长横条的样式出现,表示该函数占用了大量的 CPU 时间。

图片

然而,perf+ 火焰图在这次并没有起到太大的作用,反复统计了很多次,并没有出现梦寐以求的“长横条”,还是很和谐。

perf stat

perf+ 火焰图并没有起到很好的效果,就想换个工具继续试试,但是找来找去、请教大神,也没找到更好的工具,只好继续研究 perf 这个工具。

perf 除了上面提到的 record(记录事件)、script(解析记录的事件)命令之外,还有其他一些命令,常用的有 report(与 script 类似,都是对 perf record 记录的事件进行解析,不同之处在于 report 直接解析程序中的运行热点,script 的扩展性更强一点,可以调用外部脚本对事件数据进行解析)、stat(记录进程一段时间之内触发的事件数)、top(实时分析程序运行时热点)、list(列出 perf 可以记录的事件数)等命令。

这些命令挨个试了个遍,终于在 perf stat 命令这块有了突破:

使用 perf stat 对业务进程运行在物理机和容器上分别进行统计,发现业务进程运行在容器中时,大部分事件(task-clock、context-switches、cycles、instructions 等)的触发次数是运行在物理机上时的百分之一。

这是什么原因呢?一定是什么东西阻塞住了程序的运转,这个东西是什么呢?

前面已经分析了,不是磁盘,不是网络,也不是内存,更不是 cpu,那还有什么呢??

周三

是什么原因阻塞住了程序的运转呢?百思不得其解,百问不得其解,百猜不得其解,得,还是得动手,上控制变量法。

运行在容器中的程序和运行在物理机上有什么区别呢?我们知道,docker 容器 =cgroup+namespace+secomp+capability+selinux,那么就把这些技术一个个都去掉,看到底是哪个特性搞的鬼。

在这 5 个技术中,后三个都是安全相关的,都有开关可以控制,经过测试,发现把后三个都关掉之后,性能还是很差,说明这 3 个技术是无辜的,开始排查 cgroup 和 namespace。

首先怀疑的当然是 cgroup,毕竟它就是做资源限制的,很有可能一不小心限制错了,就把业务给限制了。

cgexec

cgexec 是 cgroup 提供的一个工具,可以在启动时就将程序运行到某个 cgroup 中,因此我们可以将业务程序运行在物理机上,但是放到业务容器所在的 cgroup 中,看看性能会不会下降。

具体用法如下:

cgexec -g *:/system.slice/docker-03c2dd57ba123879abab6f7b6da5192a127840534990c515be325450b7193c11.scope ./run.sh

通过该命令即可将 run.sh 运行在与容器 03c2dd57 相同的 cgroup 中。在多次测试之后,发现这种情况下,业务进程的运行速度没有受到影响,cgroup 被洗白,那么真相只有一个——凶手就是 namespace。

周四

虽然说凶手已经确定是 namespace,但是 namespace 家族也有一大票人,有 ipc namespace、pid namespace 等等,还需要进一步确定真凶。

nsenter

nsenter 是一个 namespace 相关的工具,通过它可以进入某个进程所在的 namespace。在 docker exec 命令出现之前,它唯一一个可以进入 docker 容器的工具,在 docker exec 出现之后,nsenter 也由于其可以选择进入哪些 namespace 而成为 docker 问题定位的一个极其重要的工具。

通过如下命令,即可进入容器所在的 mount namespace。

nsenter --target $(docker inspect --format '{{.State.Pid}}' 容器 id) --mount bash

同理,通过如下命令即可进入容器所在的 IPC namespace 和 pid namespace。

nsenter --target $(docker inspect --format '{{.State.Pid}}' 容器 id) --ipc --pid bash

在不断的将业务进程在各个 namespace 之间切换后,终于进一步锁定了真凶:mount namespace。测试发现,一旦将业务进程放置到容器所在的 mount namespace,性能就会急剧下降。

这是为什么呢?这是为什么呢?mount namespace 到底做了什么,会有这么大的影响?

离开公司时已经时 12 点,隔壁工位的专家还在那电话会议,“我看哈,这一帧,在这个节点还是有的,但是到了这呢,就没了,它。。”,“那是找到丢包原因了?”,“别急嘛,我慢慢看,看这个节点。”。

在回家的出租车上,想想这个问题已经四天了,想想隔壁工位的专家都要成神了,还是会遇到棘手的问题,突然有种崩溃的感觉,费了九牛二虎之力猜把眼泪憋回去,不然还真怕吓着出租车师傅。

周五

早上起床还和女朋友谈起这事,说我最近遇到了一个大难题,想想已经好多年没遇到这么难搞的问题了。上一次遇到这种级别的问题,还是大四刚进实验室的时候,那时候有个问题花了一整周的时间才解决。要是今天我还解决不了这个问题,就破记录了。

记得当时是需要在实验室搭建 eucalyptus 集群,之前每次搭建都很顺利,但是那次却奇怪,怎么都搭建不成功,研究了一周之后,才发现是因为那台服务器的 bios 时间被还原了,eucalyptus 在安装过程中发现当前时间不在自己的有效时间内(太早了),因此一直安装失败。

言归正传,mount namespace 为什么有这么大的威力呢?它到底影响什么了呢?实在想不通,就去请教了下大神,大神想了想,回了我句,试试 ldd?

ldd

ldd 是什么?

当然这句话我没去问大神,转身自己查去了。

ldd 是 list, dynamic, dependencies 的缩写,意思是列出动态库依赖关系。顿时豁然开朗,mount namespace 隔离出了自己的文件系统,所以容器内外可以使用不同的依赖库,而不同的依赖库就可能造成无数种影响。

于是开始通过 ldd 对比容器中业务进程的依赖库与宿主机上业务进程的依赖库,最终发现容器中的 glibc 库与宿主机上的 glibc 库版本不一致,很可能是这个原因导致性能下降的。

于是将容器中的 glibc 库版本替换为宿主机上的 glibc 库之后,容器内业务的性能终于恢复了,猜想得到证实。

下班回家,一身轻松!

路过隔壁工位的专家时候,他刚好起身接水,顺口问道,“怎么样,平哥,丢失的那一帧找到没?”,“嗨,别提了,继续看”

后记

为什么容器内外 glibc 版本不一致就导致性能下降了呢?

这是和业务模型相关的,前面提到,下游的业务模型是通过与主机共享 IPC namespace 的方式来使用共享内存与宿主机上的 daemon 进程进行通信。而 glibc 在一次升级中,更新了信号量的数据结构(如下),就会导致在共享内存通信时,由于数据格式不一致,每次信号量通信都超时,从而影响了程序运行效率。

图片


linux 截图软件 Shutter

截图软件一览

linux下有不少截图软件,包括

  • 默认gnome-screenshot

  • Flameshot

  • Shutter

  • GIMP

  • ImageMagick

  • Deepin Scrot 基于终端的一个较新的截图工具

我的需求很简单,只要可以像微信一样截图,方便做一些简单的标注即可。

使用下来感觉在 Debian 9 上 Shutter最简单,Flameshot 编译有问题就不用了,看网络介绍Flameshot也是很不错的,如果用的Debian 10 我可能会尝试下。这篇文章简单记录 Shutter 的使用情况。

Shuter 安装

debian 9 安装简单:

apt-get install shutter

命令行使用

Command Action
shutter -s 截取鼠标选取的区域
shutter -f 截取全屏
shutter -w 截取指定窗口
shutter -a 截取当前活动窗口
shutter -s -d= 延时秒,截取鼠标选取的区域

设置快捷键

全部设置-> 键盘,将命令行中的命令配置为自己熟悉的快捷键:

设置后台常驻

我在使用中发现,每次冷启动都要花费不小的时间,还会显示插件更新之类的提示。索性在首选项里选择开机自动启动。

参考资料


linux 解压 rar 文件

下载地址:https://www.rarlab.com/download.htm

image-20210601152810059

下载完后安装:

# tar -xzvf rarlinux-x64-6.0.2b1.tar.gz
# cd rar
# make

这样就安装好了,安装后就有了 rar 和 unrar 这两个命令,rar 是压缩命令,unrar 是解压命令。

压缩:

# rar a all *.jpg

解压缩:

# unrar e all.rar

其他参数感兴趣的使用 -h 自己查了。


解决 linux 命令行光标莫名消失

说来也是奇怪。我感觉应该是我在 gnome-tweak 开启过多东西的原因,里面有啥方法把光标关掉然后没有恢复吧。

直接手动设置吧:

echo -e "\033[?25h"  # 显示光标

将其设置到 .bashrc 或者 .zshrc 里:

alias ts='echo -e "\033[?25h"'

PC 断电恢复后自动启动

image-20210601162154584

首先进入BIOS 的设置主界面,找到[POWER MANAGEMENT SETUP],再找到[PWR Lost Resume State] 或者 [AC Recovery],这一项有三个选择项。

  • [Keep OFF]项,代表停电后再来电时,电脑不会自动启动。
  • [Turn On]项,代表停电后再来电时,电脑会自动启动。
  • [Last State],那么代表停电后再来电时,电脑恢复到停电前电脑的状态。断电前如果电脑是处于开机状态,那么来电后就会自动开机。断电前是处于关机状态,那么来电后电脑不会自动开机。

参考资料

  • https://blog.csdn.net/weixin_32132771/article/details/104291008

linux物理机设置 CPU Performance 模式

背景

CPU 动态节能技术用于降低服务器功耗,通过选择系统空闲状态不同的电源管理策略,可以实现不同程度降低服务器功耗,更低的功耗策略意味着 CPU 唤醒更慢对性能影响更大。

对于对时延和性能要求高的应用,需要在服务器 BIOS 中修改电源管理为 Performance,从而关闭 CPU 的动态调节功能,禁止 CPU 休眠,把 CPU 频率固定到最高。

更多关于主机电源管理的内容,可以参考我前一篇文章《一些 bios 配置优化的备忘》— C-State P-State。我们既可以在bios进行设置,也可以在OS进行设置。具体到 linux 操作系统,就是通过 cpufreq 进行配置。

查看 CPU 主频 与 实际的运行主频

grep -E '^model name|^cpu MHz' /proc/cpuinfo

在我本机可以看到,主频与实际运行的主频是不一致的:

时间1:

image-20210604112503150

时间二:

image-20210604112519187

cpufreq 的五种模式

cpufreq 是一个动态调整 cpu 频率的模块,系统启动时生成一个文件夹 /sys/devices/system/cpu/cpu0/cpufreq/,里面有几个文件,其中 scaling_min_freq 代表最低频率,scaling_max_freq 代表最高频率,scalin_governor 代表 cpu 频率调整模式,用它来控制 CPU 频率。

# 查看当前的调节器
cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor
conservative
  1. performance: 顾名思义只注重效率,将 CPU 频率固定工作在其支持的最高运行频率上,而不动态调节。
  2. Userspace: 最早的 cpufreq 子系统通过 userspace governor 为用户提供了这种灵活性。系统将变频策略的决策权交给了用户态应用程序,并提供了相应的接口供用户态应用程序调节 CPU 运行频率使用。也就是长期以来都在用的那个模式。可以通过手动编辑配置文件进行配置
  3. powersave: 将 CPU 频率设置为最低的所谓 “省电” 模式,CPU 会固定工作在其支持的最低运行频率上。因此这两种 governors 都属于静态 governor,即在使用它们时 CPU 的运行频率不会根据系统运行时负载的变化动态作出调整。这两种 governors 对应的是两种极端的应用场景,使用 performance governor 是对系统高性能的最大追求,而使用 powersave governor 则是对系统低功耗的最大追求。
  4. ondemand: 按需快速动态调整 CPU 频率, 一有 cpu 计算量的任务,就会立即达到最大频率运行,等执行完毕就立即回到最低频率;ondemand:userspace 是内核态的检测,用户态调整,效率低。而 ondemand 正是人们长期以来希望看到的一个完全在内核态下工作并且能够以更加细粒度的时间间隔对系统负载情况进行采样分析的 governor。 在 ondemand governor 监测到系统负载超过 up_threshold 所设定的百分比时,说明用户当前需要 CPU 提供更强大的处理能力,因此 ondemand governor 会将 CPU 设置在最高频率上运行。但是当 ondemand governor 监测到系统负载下降,可以降低 CPU 的运行频率时,到底应该降低到哪个频率呢? ondemand governor 的最初实现是在可选的频率范围内调低至下一个可用频率,例如 CPU 支持三个可选频率,分别为 1.67GHz、1.33GHz 和 1GHz ,如果 CPU 运行在 1.67GHz 时 ondemand governor 发现可以降低运行频率,那么 1.33GHz 将被选作降频的目标频率。
  5. conservative: 与 ondemand 不同,平滑地调整 CPU 频率,频率的升降是渐变式的, 会自动在频率上下限调整,和 ondemand 的区别在于它会按需分配频率,而不是一味追求最高频率;

设置 performance

for CPUFREQ in /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor; do
	[ -f $CPUFREQ ] || continue
	echo -n performance > $CPUFREQ
done

再查看当前调节器

cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor

image-20210604113250587

最后确认 cpu 主频已定格在最高频率,发现已全部运行在最高频率。

grep -E '^model name|^cpu MHz' /proc/cpuinfo

image-20210604112503150

注意

这个配置重启后会失效。如果需要持久化,可以设置开机自动运行本命令,或通过修改bios配置达到目的。

参考文章