在VMware ESXi上对三星PCIe 4.0 NVMe SSD 980 PRO硬盘进行直通DirectPath和虚拟化Virtualization的读写测试

在VMware ESXi上对三星PCIe 4.0 NVMe SSD 980 PRO硬盘进行直通DirectPath和虚拟化Virtualization的读写测试
存储虚拟化后,读性能损失约21.5%,写性能损失约18.4%

Read and Write Tests of Samsung PCIe 4.0 NVMe SSD 980 PRO Hard Drive with DirectPath and Virtualization on VMware ESXi

物理服务器 NF5280M5
硬盘 PCIEx4转NMVe
虚拟化软件 ESXi 7.03
虚拟机配置 8核心 16G内存 120G系统盘
操作系统 CentOS7.9
数据盘 三星 PCIe 4.0 NVMe SSD 980 PRO
测试软件 fio

1、软件安装

yum -y install epel-release
yum -y install fio

2、挂载数据目录

sudo vgcreate lvmgroup /dev/vdb
sudo lvcreate -l 100%FREE -n data lvmgroup
sudo mkfs.xfs /dev/lvmgroup/data
sudo mkdir /data
sudo echo "/dev/lvmgroup/data /data xfs defaults 0 0" >>/etc/fstab
sudo mount -av

3、编写 fio 测试配置文件:创建一个用于 fio 测试的配置文件。您可以使用文本编辑器创建一个新文件,例如 fio_test_config.fio

[global]
ioengine=libaio
direct=1
thread=1
rw=randrw
bs=4k
numjobs=4
size=32G
runtime=300
group_reporting

[randwrite]

[global]:这部分指定了全局配置,适用于所有作业。
ioengine=libaio:指定I/O引擎为libaio,表示使用异步I/O。
direct=1:启用直接I/O,绕过操作系统的文件系统缓存。
thread=1:每个作业使用一个线程。
rw=randrw:读写模式为随机读写。
bs=4k:块大小为4KB。
numjobs=4:作业数量为4,表示并发的作业数。
size=32G:每个作业的测试文件大小为32GB。
runtime=300:测试运行时间为300秒。
group_reporting:指定所有线程的统计信息应汇总在一起报告。

直通DirectPath

[root@10-53-220-58 ~]# cd /data/
[root@10-53-220-58 data]# ls
[root@10-53-220-58 data]# sudo dd if=/dev/zero of=/data/fio_test_file bs=1G count=32
32+0 records in
32+0 records out
34359738368 bytes (34 GB) copied, 36.9548 s, 930 MB/s
[root@10-53-220-58 data]# vi fio_test_config.fio
[root@10-53-220-58 data]# sudo fio fio_test_config.fio
randwrite: (g=0): rw=randrw, bs=(R) 4096B-4096B, (W) 4096B-4096B, (T) 4096B-4096B, ioengine=libaio, iodepth=1
...
fio-3.7
Starting 4 threads
randwrite: Laying out IO file (1 file / 32768MiB)
randwrite: Laying out IO file (1 file / 32768MiB)
randwrite: Laying out IO file (1 file / 32768MiB)
randwrite: Laying out IO file (1 file / 32768MiB)
Jobs: 4 (f=4): [m(4)][100.0%][r=102MiB/s,w=103MiB/s][r=26.2k,w=26.3k IOPS][eta 00m:00s] 
randwrite: (groupid=0, jobs=4): err= 0: pid=9048: Fri Apr 12 13:55:32 2024
   read: IOPS=26.0k, BW=102MiB/s (107MB/s)(29.8GiB/300001msec)
    slat (nsec): min=3381, max=69136, avg=4802.53, stdev=1677.41
    clat (usec): min=21, max=19215, avg=113.61, stdev=218.66
     lat (usec): min=34, max=19220, avg=118.47, stdev=218.66
    clat percentiles (usec):
     |  1.00th=[   48],  5.00th=[   51], 10.00th=[   53], 20.00th=[   55],
     | 30.00th=[   57], 40.00th=[   59], 50.00th=[   65], 60.00th=[   74],
     | 70.00th=[   77], 80.00th=[   85], 90.00th=[   93], 95.00th=[  343],
     | 99.00th=[ 1270], 99.50th=[ 1369], 99.90th=[ 1516], 99.95th=[ 1565],
     | 99.99th=[ 1958]
   bw (  KiB/s): min=20680, max=36128, per=24.99%, avg=26004.68, stdev=2194.12, samples=2397
   iops        : min= 5170, max= 9032, avg=6501.10, stdev=548.54, samples=2397
  write: IOPS=25.0k, BW=102MiB/s (106MB/s)(29.7GiB/300001msec)
    slat (usec): min=4, max=135, avg= 6.16, stdev= 1.90
    clat (nsec): min=1292, max=1175.4k, avg=27396.71, stdev=3962.20
     lat (usec): min=19, max=1181, avg=33.62, stdev= 4.09
    clat percentiles (nsec):
     |  1.00th=[18304],  5.00th=[21888], 10.00th=[23680], 20.00th=[24960],
     | 30.00th=[26496], 40.00th=[26752], 50.00th=[27264], 60.00th=[27520],
     | 70.00th=[28288], 80.00th=[29312], 90.00th=[31616], 95.00th=[34048],
     | 99.00th=[39168], 99.50th=[41216], 99.90th=[43776], 99.95th=[45312],
     | 99.99th=[50944]
   bw (  KiB/s): min=20280, max=36008, per=24.99%, avg=25980.38, stdev=2247.11, samples=2397
   iops        : min= 5070, max= 9002, avg=6495.02, stdev=561.78, samples=2397
  lat (usec)   : 2=0.04%, 4=0.01%, 10=0.01%, 20=0.90%, 50=50.88%
  lat (usec)   : 100=44.43%, 250=1.06%, 500=0.46%, 750=0.46%, 1000=0.53%
  lat (msec)   : 2=1.22%, 4=0.01%, 10=0.01%, 20=0.01%
  cpu          : usr=4.49%, sys=11.07%, ctx=15587579, majf=0, minf=10
  IO depths    : 1=100.0%, 2=0.0%, 4=0.0%, 8=0.0%, 16=0.0%, 32=0.0%, >=64=0.0%
     submit    : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
     complete  : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
     issued rwts: total=7804560,7797520,0,0 short=0,0,0,0 dropped=0,0,0,0
     latency   : target=0, window=0, percentile=100.00%, depth=1

Run status group 0 (all jobs):
   READ: bw=102MiB/s (107MB/s), 102MiB/s-102MiB/s (107MB/s-107MB/s), io=29.8GiB (31.0GB), run=300001-300001msec
  WRITE: bw=102MiB/s (106MB/s), 102MiB/s-102MiB/s (106MB/s-106MB/s), io=29.7GiB (31.9GB), run=300001-300001msec

Disk stats (read/write):
    dm-2: ios=7801557/7794611, merge=0/0, ticks=862107/186550, in_queue=1048584, util=100.00%, aggrios=7804560/7797562, aggrmerge=0/1, aggrticks=857542/181607, aggrin_queue=1039149, aggrutil=100.00%
  nvme0n1: ios=7804560/7797562, merge=0/1, ticks=857542/181607, in_queue=1039149, util=100.00%
www.zhangfangzhou.cn

虚拟化Virtualization

[root@10-53-220-44 data]# sudo dd if=/dev/zero of=/data/fio_test_file bs=1G count=32
32+0 records in
32+0 records out
34359738368 bytes (34 GB) copied, 71.8294 s, 478 MB/s
[root@10-53-220-44 data]# vi fio_test_config.fio
[root@10-53-220-44 data]# sudo fio fio_test_config.fio
randwrite: (g=0): rw=randrw, bs=(R) 4096B-4096B, (W) 4096B-4096B, (T) 4096B-4096B, ioengine=libaio, iodepth=1
...
fio-3.7
Starting 4 threads
randwrite: Laying out IO file (1 file / 32768MiB)
randwrite: Laying out IO file (1 file / 32768MiB)
randwrite: Laying out IO file (1 file / 32768MiB)
randwrite: Laying out IO file (1 file / 32768MiB)
Jobs: 4 (f=4): [m(4)][100.0%][r=78.2MiB/s,w=77.8MiB/s][r=20.0k,w=19.9k IOPS][eta 00m:00s]
randwrite: (groupid=0, jobs=4): err= 0: pid=9016: Fri Apr 12 14:43:21 2024
   read: IOPS=20.4k, BW=79.7MiB/s (83.6MB/s)(23.4GiB/300001msec)
    slat (usec): min=4, max=114, avg= 6.78, stdev= 1.98
    clat (usec): min=42, max=38534, avg=134.39, stdev=190.16
     lat (usec): min=53, max=38545, avg=141.24, stdev=190.14
    clat percentiles (usec):
     |  1.00th=[   79],  5.00th=[   87], 10.00th=[   89], 20.00th=[   92],
     | 30.00th=[   93], 40.00th=[   96], 50.00th=[   98], 60.00th=[  101],
     | 70.00th=[  104], 80.00th=[  106], 90.00th=[  113], 95.00th=[  161],
     | 99.00th=[ 1205], 99.50th=[ 1319], 99.90th=[ 1467], 99.95th=[ 1516],
     | 99.99th=[ 2057]
   bw (  KiB/s): min=   73, max=24856, per=16.35%, avg=13347.32, stdev=9723.44, samples=2397
   iops        : min=   18, max= 6214, avg=3336.67, stdev=2431.02, samples=2397
  write: IOPS=20.4k, BW=79.6MiB/s (83.5MB/s)(23.3GiB/300001msec)
    slat (usec): min=5, max=115, avg= 8.06, stdev= 1.98
    clat (nsec): min=1403, max=38544k, avg=44914.21, stdev=37185.93
     lat (usec): min=32, max=38560, avg=53.04, stdev=37.23
    clat percentiles (usec):
     |  1.00th=[   36],  5.00th=[   39], 10.00th=[   40], 20.00th=[   42],
     | 30.00th=[   43], 40.00th=[   44], 50.00th=[   45], 60.00th=[   46],
     | 70.00th=[   47], 80.00th=[   48], 90.00th=[   50], 95.00th=[   52],
     | 99.00th=[   57], 99.50th=[   59], 99.90th=[   69], 99.95th=[   87],
     | 99.99th=[  135]
   bw (  KiB/s): min=   71, max=25352, per=16.36%, avg=13341.18, stdev=9726.48, samples=2397
   iops        : min=   17, max= 6338, avg=3335.13, stdev=2431.78, samples=2397
  lat (usec)   : 2=0.01%, 10=0.01%, 20=0.01%, 50=45.37%, 100=33.22%
  lat (usec)   : 250=19.16%, 500=0.43%, 750=0.43%, 1000=0.46%
  lat (msec)   : 2=0.91%, 4=0.01%, 10=0.01%, 20=0.01%, 50=0.01%
  cpu          : usr=3.53%, sys=11.43%, ctx=12237590, majf=0, minf=11
  IO depths    : 1=100.0%, 2=0.0%, 4=0.0%, 8=0.0%, 16=0.0%, 32=0.0%, >=64=0.0%
     submit    : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
     complete  : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
     issued rwts: total=6121601,6116013,0,0 short=0,0,0,0 dropped=0,0,0,0
     latency   : target=0, window=0, percentile=100.00%, depth=1

Run status group 0 (all jobs):
   READ: bw=79.7MiB/s (83.6MB/s), 79.7MiB/s-79.7MiB/s (83.6MB/s-83.6MB/s), io=23.4GiB (25.1GB), run=300001-300001msec
  WRITE: bw=79.6MiB/s (83.5MB/s), 79.6MiB/s-79.6MiB/s (83.5MB/s-83.5MB/s), io=23.3GiB (25.1GB), run=300001-300001msec

Disk stats (read/write):
    dm-2: ios=6120646/6115090, merge=0/0, ticks=806337/255779, in_queue=1062184, util=100.00%, aggrios=6121601/6116035, aggrmerge=0/1, aggrticks=801719/251319, aggrin_queue=1051124, aggrutil=100.00%
  sdb: ios=6121601/6116035, merge=0/1, ticks=801719/251319, in_queue=1051124, util=100.00%
www.zhangfangzhou.cn

4、结果
直通 (DirectPath)
read: IOPS=26.0k, BW=102MiB/s (107MB/s)(29.8GiB/300001msec)
write: IOPS=25.0k, BW=102MiB/s (106MB/s)(29.7GiB/300001msec)

虚拟化Virtualization
read: IOPS=20.4k, BW=79.7MiB/s (83.6MB/s)(23.4GiB/300001msec)
write: IOPS=20.4k, BW=79.6MiB/s (83.5MB/s)(23.3GiB/300001msec)

 

读取 (Read) 写入 (Write) 带宽 (Bandwidth)
直通 (DirectPath) 26.0k 25.0k 102MiB/s (107MB/s)
虚拟化 (Virtualization) 20.4k 20.4k 79.7MiB/s (83.6MB/s)

存储虚拟化后,读性能损失约21.5%,写性能损失约18.4%

CentOS Linux release 7.9.2009 编译安装最新版HAProxy 2.8 LTS长期支持版,并创建Shell监听脚本

编译安装HAProxy 2.8 LTS版本,官方源码包下载地址:http://www.haproxy.org/download/

由于CentOS7 之前版本自带的lua版本比较低并不符合HAProxy要求的lua最低版本(5.3)的要求,因此需要编译安装较新版本的lua环境,然后才能编译安装HAProxy。

1、查看现有的lua版本,如果版本太旧需要先更新lua

lua -v 
Lua 5.1.4  Copyright (C) 1994-2008 Lua.org, PUC-Rio

2、安装基础命令及编译依赖环境

yum install gcc readline-devel

3、下载和编译lua-5.4.6

cd /usr/local/src
wget --no-check-certificate https://www.lua.org/ftp/lua-5.4.6.tar.gz
tar xvf lua-5.4.6.tar.gz

开始编译

cd  lua-5.4.6
make linux test

查看编译安装的版本
src/lua -v
Lua 5.4.6  Copyright (C) 1994-2023 Lua.org, PUC-Rio

把旧版本移走,换成新的版本
mv /usr/bin/lua /usr/bin/lua.old
cp /usr/local/src/lua-5.4.6/src/lua /usr/bin/lua

确认现在的版本
lua -v 
Lua 5.4.6  Copyright (C) 1994-2023 Lua.org, PUC-Rio

4、安装Haproxy

创建用户
useradd -r -s /sbin/nologin haproxy

5、安装依赖

yum -y install gcc openssl-devel pcre-devel systemd-devel

6、下载和编译

wget --no-check-certificate  https://www.haproxy.org/download/2.8/src/haproxy-2.8.9.tar.gz
tar xvf haproxy-2.8.9.tar.gz
cd haproxy-2.8.9/


make TARGET=linux-glibc USE_OPENSSL=1 USE_PCRE=1 USE_SYSTEMD=1 USE_LUA=1 LUA_INC=/usr/local/src/lua-5.4.6/src LUA_LIB=/usr/local/src/lua-5.4.6/src
make install PREFIX=/etc/haproxy

创建软连接
ln -s /etc/haproxy/sbin/haproxy /usr/bin/haproxy
www.zhangfangzhou.cn
查看版本
haproxy -v
HAProxy version 2.8.9-1842fd0 2024/04/05 - https://haproxy.org/
Status: long-term supported branch - will stop receiving fixes around Q2 2028.
Known bugs: http://www.haproxy.org/bugs/bugs-2.8.9.html
Running on: Linux 3.10.0-1160.105.1.el7.x86_64 #1 SMP Thu Dec 7 15:39:45 UTC 2023 x86_64

7、创建配置文件

vi /etc/haproxy/haproxy.cfg
global
  maxconn 100000
  chroot /etc/haproxy
  stats socket /var/tmp/haproxy.sock mode 600 level admin
  user haproxy
  group haproxy
  daemon
  pidfile /var/tmp/haproxy.pid

defaults
  option http-keep-alive
  option forwardfor
  maxconn 100000
  mode http
  timeout connect 300000ms
  timeout client 300000ms
  timeout server 300000ms

listen stats
  mode http
  bind 0.0.0.0:3306
  stats enable
  log global
  stats uri /haproxy-status
  stats auth haadmin:Admin@2018..

listen db_port
  bind :3306
  mode tcp
  log global
  balance roundrobin
  option tcplog
  server db1 10.53.123.104:3306 check inter 3000 fall 2 rise 3
  server db2 10.53.123.105:3306 check inter 3000 fall 2 rise 3
  server db3 10.53.123.106:3306 check inter 3000 fall 2 rise 3


8、创建service服务

vi /usr/lib/systemd/system/haproxy.service
[Unit]
Description=HAProxy Load Balancer
After=syslog.target network.target

[Service]
ExecStartPre=/usr/bin/haproxy -f /etc/haproxy/haproxy.cfg -c -q
ExecStart=/usr/bin/haproxy -Ws -f /etc/haproxy/haproxy.cfg
ExecReload=/bin/kill -USR2 $MAINPID
LimitNOFILE=100000

[Install]
WantedBy=multi-user.target

systemctl enable haproxy
systemctl start haproxy
9、设置监听脚本

vi ha_watchdog.sh
#!/bin/bash
#www.zhangfangzhou.cn
# 定义日志文件路径
LOG_FILE="/var/log/haproxy_watchdog.log"

# 定义 HAProxy 进程的名称
HAPROXY_PROCESS="haproxy"

# 检查 HAProxy 进程是否在运行
check_haproxy_process() {
    # 使用 pgrep 命令检查是否存在名为 haproxy 的进程
    pgrep -x $HAPROXY_PROCESS > /dev/null
}

# 启动 HAProxy 进程
start_haproxy() {
    echo "$(date +'%Y-%m-%d %H:%M:%S') - Starting HAProxy..." >> $LOG_FILE
    systemctl start haproxy
}

# 主循环
while true; do
    # 检查 HAProxy 进程是否在运行
    if ! check_haproxy_process; then
        # 如果进程不存在,则重新启动 HAProxy 并记录日志
        start_haproxy
    fi
    # 休眠一段时间后再次检查
    sleep 60
done


#设置开机启动
chmod +x ha_watchdog.sh

vi /etc/rc.local
nohup /root/ha_watchdog.sh &

一台 Linux 服务器最多能支撑多少个 TCP 连接?

一台 Linux 服务器最多能支撑多少个 TCP 连接?一台Linux机器上最多能建立多少个TCP连接?

困惑很多人的并发问题

我发现有很多同学对一个基础问题始终是没有彻底搞明白。那就是一台服务器最大究竟能支持多少个网络连接?我想我有必要单独发一篇文章来好好说一下这个问题。

很多同学看到这个问题的第一反应是65535。原因是:“听说端口号最多有65535个,那长连接就最多保持65535个了”。是这样的吗?还有的人说:“应该受TCP连接里四元组的空间大小限制,算起来是200多万亿个!”
如果你对这个问题也是理解的不够彻底,那么今天讲个故事讲给你听!

一次关于服务器端并发的聊天

"TCP连接四元组是源IP地址、源端口、目的IP地址和目的端口。任意一个元素发生了改变,那么就代表的是一条完全不同的连接了。拿我的Nginx举例,它的端口是固定使用80。另外我的IP也是固定的,这样目的IP地址、目的端口都是固定的。剩下源IP地址、源端口是可变的。所以理论上我的Nginx上最多可以建立2的32次方(ip数)×2的16次方(port数)个连接。这是两百多万亿的一个大数字!!"

"进程每打开一个文件(linux下一切皆文件,包括socket),都会消耗一定的内存资源。如果有不怀好心的人启动一个进程来无限的创建和打开新的文件,会让服务器崩溃。所以linux系统出于安全角度的考虑,在多个位置都限制了可打开的文件描述符的数量,包括系统级、用户级、进程级。这三个限制的含义和修改方式如下:"

  • 系统级:当前系统可打开的最大数量,通过fs.file-max参数可修改
  • 用户级:指定用户可打开的最大数量,修改/etc/security/limits.conf
  • 进程级:单个进程可打开的最大数量,通过fs.nr_open参数可修改

"我的接收缓存区大小是可以配置的,通过sysctl命令就可以查看。"

sysctl -a | grep rmem
net.ipv4.tcp_rmem = 4096 87380 8388608
net.core.rmem_default = 212992
net.core.rmem_max = 8388608

"其中在tcp_rmem"中的第一个值是为你们的TCP连接所需分配的最少字节数。该值默认是4K,最大的话8MB之多。也就是说你们有数据发送的时候我需要至少为对应的socket再分配4K内存,甚至可能更大。"

"TCP分配发送缓存区的大小受参数net.ipv4.tcp_wmem配置影响。"

sysctl -a | grep wmem
net.ipv4.tcp_wmem = 4096 65536 8388608
net.core.wmem_default = 212992
net.core.wmem_max = 8388608

"在net.ipv4.tcp_wmem"中的第一个值是发送缓存区的最小值,默认也是4K。当然了如果数据很大的话,该缓存区实际分配的也会比默认值大。"

服务端百万连接达成记

“准备啥呢,还记得前面说过Linux对最大文件对象数量有限制,所以要想完成这个实验,得在用户级、系统级、进程级等位置把这个上限加大。我们实验目的是100W,这里都设置成110W,这个很重要!因为得保证做实验的时候其它基础命令例如ps,vi等是可用的。“

活动连接数量确实达到了100W:

ss -n | grep ESTAB | wc -l  
1000024

当前机器内存总共是3.9GB,其中内核Slab占用了3.2GB之多。MemFree和Buffers加起来也只剩下100多MB了:

cat /proc/meminfo
MemTotal:        3922956 kB
MemFree:           96652 kB
MemAvailable:       6448 kB
Buffers:           44396 kB
......
Slab:          3241244KB kB

通过slabtop命令可以查看到densty、flip、sock_inode_cache、TCP四个内核对象都分别有100W个:

结语

互联网后端的业务特点之一就是高并发. 但是一台服务器最大究竟能支持多少个TCP连接,这个问题似乎却又在困惑着很多同学。希望今天过后,你能够将这个问题踩在脚下摩擦!

转载于 https://mp.weixin.qq.com/s/Lkyj42NtvqEj63DoCY5btQ

在Ubuntu 20.04 LTS安装Docker,使用Docker安装Minio存储服务器

在Ubuntu 20.04 LTS安装Docker,使用Docker安装Minio存储服务器,使用Minio Docker镜像,在4块盘中启动基于纠删码的Minio服务
MinIO 是一个基于Apache License v2.0开源协议的对象存储服务( High Performance Object Storage)。
它兼容亚马逊S3云存储服务接口,非常适合于存储大容量非结构化的数据,MinIO是一个非常轻量的服务,可以很简单的和其他应用的结合。
Build high performance data infrastructure for machine learning, analytics and application data workloads with MinIO。
Minio使用纠删码erasure code和checksum来保护数据免受硬件故障和无声数据损坏。 即便您丢失一半数量(N/2)的硬盘,您仍然可以恢复数据。

a、在Ubuntu 20.04我们将启用Docker存储库,导入存储库GPG密钥,然后安装该软件包。
首先,更新程序包索引并安装添加新的HTTPS仓库所需的依赖项:
sudo apt update
sudo apt install apt-transport-https ca-certificates curl gnupg-agent software-properties-common

b、使用以下curl命令导入存储库的GPG密钥
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -

c、将Docker APT存储库添加到您的系统中
sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"

d、现在已启用Docker存储库,您可以安装存储库中可用的任何Docker版本
要安装最新版本的Docker,请运行以下命令。如果要安装特定的Docker版本,请跳过此步骤并转到下一个。
sudo apt update
sudo apt install docker-ce docker-ce-cli containerd.io

e、要安装特定版本,请首先列出Docker存储库中的所有可用版本
sudo apt update
apt list -a docker-ce

可用的Docker版本打印在第二列中。在撰写本文时,官方Docker存储库中只有一个Docker版本(5:19.03.9~3-0~ubuntu-focal)。
docker-ce/focal 5:19.03.9~3-0~ubuntu-focal amd64

安装完成后,Docker服务将自动启动。您可以通过键入以下内容进行验证:
sudo systemctl status docker

f、当发布新版本的Docker时,您可以使用标准sudo apt update && sudo apt upgrade过程来更新软件包

g、如果要阻止更新Docker软件包,请将其标记为“阻止”:
sudo apt-mark hold docker-ce

h、以非root用户身份执行Docker命令
默认情况下,只有具有sudo特权的 root和用户可以执行Docker命令。
要以非root用户身份执行Docker命令,您需要将用户添加到在Docker CE软件包安装过程中创建的docker组中。
sudo usermod -aG docker $USER
$USER是保存您的用户名的环境变量。
注销并重新登录,以便刷新组成员身份

i、卸载Docker
在卸载Docker之前,最好删除所有容器,映像,卷和网络。

运行以下命令以停止所有正在运行的容器并删除所有docker对象:
docker container stop $(docker container ls -aq)
docker system prune -a --volumes

g、Docker卸载
sudo apt purge docker-ce
sudo apt autoremove
--------------------------------------------------------------------------------------
k、使用Minio Docker镜像,在4块盘中启动基于纠删码的Minio服务
docker run -itd -p 9000:9000 --name minio \
-e "MINIO_ACCESS_KEY=user" \
-e "MINIO_SECRET_KEY=zhangfangzhou" \
-v /data1:/data1 \
-v /data2:/data2 \
-v /data3:/data3 \
-v /data4:/data4 \
minio/minio server /data{1..4}

-i 以交互模式运行容器,通常与 -t 同时使用
-t 为容器重新分配一个伪输入终端,通常与 -i 同时使用
-d 后台运行容器,并返回容器ID
-p 表示映射容器的端口,hostPort:containerPort(服务器端口:容器端口)
-v 挂载宿主机的一个目录,(前面的目录是服务器目录,后面的目录是容器内目录)
data1,data2,data3,data4(服务器的存储目录)
/dev/sdb1 /data1 ext4 defaults 0 0
/dev/sdc1 /data2 ext4 defaults 0 0
/dev/sdd1 /data3 ext4 defaults 0 0
/dev/sde1 /data4 ext4 defaults 0 0


l、打开浏览器输入http://www.zhangfangzhou.cn:9000/minio
输入账户密码
账户user
密码 zhangfangzhou

m、在右下角找到Create bucket,创建一个新的 bucket,然后上传文件

n、 验证是否设置成功
你可以随意拔掉硬盘,看Minio是否可以正常读写。
n、查看存储文件

CentOS 7.8使用devtoolset-9使用高版本gcc version 9.3.1 20200408 (Red Hat 9.3.1-2) (GCC)编译安装Redis 6.0.5

CentOS 7.8 编译安装Redis 6.0.5报错
In file included from server.c:30:0:
server.h:1045:5: error: expected specifier-qualifier-list before ‘_Atomic’
_Atomic unsigned int lruclock; /* Clock for LRU eviction */
^
server.c: In function ‘serverLogRaw’:
server.c:1028:31: error: ‘struct redisServer’ has no member named ‘logfile’
int log_to_stdout = server.logfile[0] == '\0';
^
server.c:1031:23: error: ‘struct redisServer’ has no member named ‘verbosity’
if (level < server.verbosity) return;
^
server.c:1033:47: error: ‘struct redisServer’ has no member named ‘logfile’
fp = log_to_stdout ? stdout : fopen(server.logfile,"a");
^
server.c:1046:47: error: ‘struct redisServer’ has no member named ‘timezone’
nolocks_localtime(&tm,tv.tv_sec,server.timezone,server.daylight_active);
^
server.c:1046:63: error: ‘struct redisServer’ has no member named ‘daylight_active’
nolocks_localtime(&tm,tv.tv_sec,server.timezone,server.daylight_active);
......
......

问题原因
CentOS 7的gcc版本为4.8.5,Redis 6.0.5最低需要gcc4.9,因此需要升级gcc版本
from redis 6.0.5, building redis from source code needs C11 support.The version of gcc in CentOS 7 is 4.8.5, but C11 was introduced in 4.9.

解决办法
1、手动编译gcc大于4.9的版本
2、安装 devtoolset-9(使用高版本gcc version 9.3.1 20200408 (Red Hat 9.3.1-2) (GCC))编译安装Redis 6.0.5
yum install centos-release-scl -y
yum install devtoolset-9 -y

临时使用高版本gcc version 9.3.1 20200408 (Red Hat 9.3.1-2) (GCC) (推荐使用这个方法)
export CC=/opt/rh/devtoolset-9/root/usr/bin/gcc
export CPP=/opt/rh/devtoolset-9/root/usr/bin/cpp
export CXX=/opt/rh/devtoolset-9/root/usr/bin/c++

wget http://download.redis.io/releases/redis-stable.tar.gz
tar zxf redis-stable.tar.gz && cd redis-stable
make -j2 && make install
if [ -f "/root/redis-stable/src/redis-server" ]; then
mkdir -p /usr/local/redis/{bin,etc,var}
/bin/cp /root/redis-stable/src/{redis-benchmark,redis-check-aof,redis-check-rdb,redis-cli,redis-sentinel,redis-server} /usr/local/redis/bin/
/bin/cp /root/redis-stable/redis.conf /usr/local/redis/etc/

cd /root/redis-stable/src
id -u redis >/dev/null 2>&1
[ $? -ne 0 ] && useradd -M -s /sbin/nologin redis

chown -R redis:redis /usr/local/redis/{var,etc}
#
if [ -e /bin/systemctl ]; then
cat > /lib/systemd/system/redis-server.service << "EOF"
[Unit]
Description=Redis In-Memory Data Store
After=network.target

[Service]
Type=forking
PIDFile=/var/run/redis/redis.pid
User=redis
Group=redis

Environment=statedir=/var/run/redis
PermissionsStartOnly=true
ExecStartPre=/bin/mkdir -p ${statedir}
ExecStartPre=/bin/chown -R redis:redis ${statedir}
ExecStart=/usr/local/redis/bin/redis-server /usr/local/redis/etc/redis.conf
ExecStop=/bin/kill -s TERM $MAINPID
Restart=always
LimitNOFILE=1000000
LimitNPROC=1000000
LimitCORE=1000000

[Install]
WantedBy=multi-user.target
EOF
systemctl enable redis-server

#确认Redis 6.0.5版本
[www@zhangfangzhou_cn ~]# redis-server -v
Redis server v=6.0.5 sha=00000000:0 malloc=jemalloc-5.1.0 bits=64 build=1987ac006866aa00

CentOS7.7安装 devtoolset-8(使用高版本gcc (GCC) 8.3.1 20190311)编译安装aria2-1.35.0
CentOS6安装devtoolset(使用高版本gcc)GCC 4.8 GCC 4.9 GCC 5.2

如何编译Linux Kernel(linux-5.6.12内核)并制作成rpm文件

如何编译内核及制作RPM包
CentOS 7 编译Linux Kernel(linux-5.6.12内核)并制作成rpm文件
1、下载Latest Stable Kernel
wget https://cdn.kernel.org/pub/linux/kernel/v5.x/linux-5.6.12.tar.xz
tar -Jxf linux-5.6.12.tar.xz

2、安装依赖包
yum -y install openssh-devel elfutils-libelf-devel bc

3、从 /boot 目录将现有版本的内核编译config配置文件拷过来到放到新的内核源码解压目录内并重命名为.config的隐藏文件(这个文件保存了在安装系统时内核所安装的模块配置信,否则需要重新手动指定每一个模块的编译配置)
cd linux-5.6.12
cp /boot/config-3.10.0-1062.el7.x86_64 ./.config
或者
cp /boot/config-$(uname -r) ./.config

3、安装开发工具包组
yum -y groupinstall "development tools"

4、安装ncurse-devel包 (make menuconfig 文本界面窗口依赖包)
yum -y install ncurses-devel
运行 make menuconfig,开启文本界面的编译选项菜单窗口,可以对内核加载的模块编译选项进行调整,如修改编译后的内核名称、新添加之前系统缺少的模块等
make menuconfig

(1)修改内核名称
General setup --->local version -append to kernel release #注意不要有空格

-----------
出现空格的话会产生错误错误
[root@www.zhangfangzhou.cn linux-5.6.12]# sudo make modules_install
ln: target ‘5.6.12_zhangfangzhou.cn_20200510/source’ is not a directory
make[1]: *** [_modinst_] Error 1
make: *** [sub-make] Error 2
-----------

(2)新添加NTFS文件系统支持模块
File systems --->DOS/FAT/NT Filesystems --->NTFS file system support

5、确认配置文件中NTFS功能是否添加成功
vi .config

6、编译内核 #时间较长,具体时间根据硬件性能决定
make -j `cat /proc/cpuinfo | grep 'model name'|wc -l`
或者
## get thread or cpu core count using nproc command ##
make -j $(nproc)

7、编译安装模块
编译完成后执行make modules_install 安装内核模块
make modules_install

8、安装内核核心文件
make install

9、制作成linux-5.6.12内核rpm文件
yum -y install rpmdevtools

cd linux-5.6.12
make rpm-pkg ##同时构建源和二进制RPM软件包
或者
make binrpm-pkg ##仅构建二进制RPM软件包

Checking for unpackaged file(s): /usr/lib/rpm/check-files /root/rpmbuild/BUILDROOT/kernel-5.6.12_zhangfangzhou.cn_20200510-1.x86_64
Wrote: /root/rpmbuild/SRPMS/kernel-5.6.12_zhangfangzhou.cn_20200510-1.src.rpm
Wrote: /root/rpmbuild/RPMS/x86_64/kernel-5.6.12_zhangfangzhou.cn_20200510-1.x86_64.rpm
Wrote: /root/rpmbuild/RPMS/x86_64/kernel-headers-5.6.12_zhangfangzhou.cn_20200510-1.x86_64.rpm
Wrote: /root/rpmbuild/RPMS/x86_64/kernel-devel-5.6.12_zhangfangzhou.cn_20200510-1.x86_64.rpm

10、CentOS 7 更换最新内核
egrep ^menuentry /etc/grub2.cfg | cut -f 2 -d \' #查看内核版本
grub2-set-default 0

reboot重启

11、Debian/Ubuntu 更换最新内核
sudo update-initramfs -c -k 5.6.12
sudo update-grub

12、查看内核版本
uname -msr
Linux 5.6.12_zhangfangzhou.cn_20200510 x86_64
----------
#https://linuxconfig.org/how-to-compile-vanilla-linux-kernel-from-source-on-fedora
#https://linuxhint.com/compile-linux-kernel-centos7/

nginx.service start-pre operation timed out. Terminating.

问题
服务器重启后Nginx服务不会自动启动,手动启动Nginx服务没有出现任何问题。

错误状态
#systemctl status nginx
nginx.service - nginx - high performance web server
Loaded: loaded (/usr/lib/systemd/system/nginx.service; enabled; vendor preset: disabled)
Active: failed (Result: timeout) since Fri 2020-02-28 19:13:13 CST; 6min ago
Docs: http://nginx.org/en/docs/
Process: 806 ExecStartPre=/usr/local/nginx/sbin/nginx -t -c /usr/local/nginx/conf/nginx.conf (code=killed, signal=TERM)

Feb 28 19:11:43 izj6cdtn3gxvjysis55g0hz systemd[1]: Starting nginx - high performance web server...
Feb 28 19:13:13 izj6cdtn3gxvjysis55g0hz systemd[1]: nginx.service start-pre operation timed out. Terminating.
Feb 28 19:13:13 izj6cdtn3gxvjysis55g0hz systemd[1]: Failed to start nginx - high performance web server.
Feb 28 19:13:13 izj6cdtn3gxvjysis55g0hz systemd[1]: Unit nginx.service entered failed state.
Feb 28 19:13:13 izj6cdtn3gxvjysis55g0hz systemd[1]: nginx.service failed.

#journalctl -u nginx.service
-- Logs begin at Sat 2020-02-29 03:11:38 CST, end at Fri 2020-02-28 19:20:01 CST. --
Feb 28 19:11:43 izj6cdtn3gxvjysis55g0hz systemd[1]: Starting nginx - high performance web server...
Feb 28 19:13:13 izj6cdtn3gxvjysis55g0hz systemd[1]: nginx.service start-pre operation timed out. Terminating.
Feb 28 19:13:13 izj6cdtn3gxvjysis55g0hz systemd[1]: Failed to start nginx - high performance web server.
Feb 28 19:13:13 izj6cdtn3gxvjysis55g0hz systemd[1]: Unit nginx.service entered failed state.
Feb 28 19:13:13 izj6cdtn3gxvjysis55g0hz systemd[1]: nginx.service failed.

原因
没有足够的超时值来启动Nginx服务

解决办法
vim /usr/lib/systemd/system/nginx.service
增加TimeoutStartSec参数值:
[Service]
...
TimeoutStartSec=600
-------------------------------------------
例子
cat /usr/lib/systemd/system/nginx.service
[Unit]
Description=nginx - high performance web server
Documentation=http://nginx.org/en/docs/
After=network-online.target remote-fs.target nss-lookup.target
Wants=network-online.target

[Service]
Type=forking
PIDFile=/var/run/nginx.pid
ExecStartPost=/bin/sleep 0.1
ExecStartPre=/usr/local/nginx/sbin/nginx -t -c /usr/local/nginx/conf/nginx.conf
ExecStart=/usr/local/nginx/sbin/nginx -c /usr/local/nginx/conf/nginx.conf
ExecReload=/usr/local/nginx/sbin/nginx -s reload
ExecStop=/usr/local/nginx/sbin/nginx -s stop
PrivateTmp=true
LimitNOFILE=51200
LimitNPROC=51200
LimitCORE=51200
TimeoutStartSec=600

[Install]
WantedBy=multi-user.target
--------------------------------------------

这个情况也可能出现在其他服务上面,没有足够的超时值来启动Nginx或Apache或者其他服务

CentOS7
使用任何文本编辑器(例如vi)打开初始化init脚本:
对于Apache: /usr/lib/systemd/system/httpd.service
对于nginx: /usr/lib/systemd/system/nginx.service

增加TimeoutStartSec参数值
[Service]
...
TimeoutStartSec=600

Debian9或者Ubuntu18
可以使用以下命令找到确切初始化脚本
systemctl status apache2.service | grep loaded
systemctl status nginx.service | grep loaded

使用任何文本编辑器(例如vi)打开初始化init脚本:
对于Apache:/lib/systemd/system/apache2.service
对于nginx:/lib/systemd/system/nginx.service

增加TimeoutStartSec参数值
[Service]
...
TimeoutStartSec=600
https://support.plesk.com/hc/en-us/articles/213387149-Nginx-Apache-are-not-running-after-server-reboot-on-a-Plesk-server-service-start-operation-timed-out-Terminating

Baidu Sitemap Generator 报错,WordPress发现了您的插件造成的错误:Baidu Sitemap Generator

升级PHP7.3之后,发现WordPress的Baidu Sitemap Generator在生成百度 XMLSitemap 生成器插件出现如下错误
错误详情
============
错误类别E_ERROR发生在文件www.zhangfangzhou.cn/wp-content/plugins/baidu-sitemap-generator/sitemap-function.php的439行。错误信息:Uncaught Error: Call to undefined function split() in www.zhangfangzhou.cn/wp-content/plugins/baidu-sitemap-generator/sitemap-function.php:439
Stack trace:
#0 www.zhangfangzhou.cn/wp-content/plugins/baidu-sitemap-generator/baidu_sitemap.php(278): xml_annotate()
#1 www.zhangfangzhou.cn/wp-content/plugins/baidu-sitemap-generator/baidu_sitemap.php(264): build_baidu_sitemap_xml('https...', 1)
#2 www.zhangfangzhou.cn/wp-content/plugins/baidu-sitemap-generator/baidu_sitemap.php(110): build_baidu_sitemap(1)
......
......
因为这款插件一直没有更新,PHP7版本废弃了一些PHP函数,split这个函数在PHP7版本已经不支持了,因此必须替换成PHP7版本的preg_split函数。

修复Baidu Sitemap Generator 报错需要修改2个地方

1、修改Baidu Sitemap Generator插件目录下的sitemap-function.php文件的439行和baidu_sitemap.php文件的308行
修改成

list( $today_year, $today_month, $today_day, $hour, $minute, $second ) = preg_split( '([^0-9])', $blogtime );

就是用preg_split替换掉split

2、修改Baidu Sitemap Generator插件目录下的baidu_sitemap.php


function baidu_sitemap_menu() {
/** Add a page to the options section of the website **/
if (current_user_can('manage_options'))
add_options_page("Baidu-Sitemap","Baidu-Sitemap", 8, __FILE__, 'baidu_sitemap_optionpage')
}
修改成
function baidu_sitemap_menu() {
/** Add a page to the options section of the website **/
if (current_user_can('manage_options'))
add_options_page("Baidu-Sitemap","Baidu-Sitemap", 'manage_options', __FILE__, 'baidu_sitemap_optionpage');
}

就是把8换成'manage_options'
修改完成后重启PHP,即可更新百度 XMLSitemap