欧拉PageCache的内核编译

欧拉 Page Cache 的内核编译 PageCache提供了一种限制page cache的能力,能够对page cache的总量进行控制, 增强系统在数据库等page cache占比较高场景下的稳定性,积极释放缓存。 它提供了以下sysctl接口: vm.pagecache_limit_ratio:pagecache占系统总内存的百分比,[0, 100],0和100都表示功能关闭。 vm.pagecache_limit_reclaim_ratio:针对pagecache真实回收的比例,在实际回收时,总是比pagecache_limit_ratio的多回收一些,默认比例是2%。 vm.pagecache_limit_ignore_dirty:在回收时是否忽略脏页,默认忽略。因为对脏页的回收较耗时。 补丁是基于 openEuler-22.03-LTS 的,不适用于 24.03-LTS,代码都已不同了 编译过程如下: 一、安装好openEuler-22.03-LTS,磁盘留够空间,最少留20G 二、安装编译已经所需软件 dnf install -y rpm-build openssl-devel bc rsync gcc gcc-c++ flex bison m4 elfutils-libelf-devel dnf install -y python dnf install -y ncurses-devel dnf install -y dwarves 三、安装内核源代码 dnf install -y kernel-source 现在是2024年11月4日,内核版本是 linux-5.10.0-60.139.0.166.oe2203.x86_64,注意补丁的适用范围 四、打补丁 page.patch 将page.patch 放到 /usr/src cd /usr/src/linux-5.10.0-60.139.0.166.oe2203.x86_64 patch -p1 < ../page.patch 五、编辑内核版本号,EXTRAVERSION的版本号要大于当前内核版本,否则无法安装。当前是166,改成+1,167 cd /usr/src/linux-5.10.0-60.139.0.166.oe2203.x86_64 vi Makefile # SPDX-License-Identifier: GPL-2.0 VERSION = 5 PATCHLEVEL = 10 SUBLEVEL = 0 EXTRAVERSION = -60.139.0.167.oe2203.x86_64 NAME = Kleptomaniac Octopus OPENEULER_MAJOR = 2203 OPENEULER_MINOR = 0 六、编译 ...

2025年08月08日 · 1 分钟 · 176 字 · 八戒

为极客天成改写一套CSI存储插件

极客天成有个很厉害的scaleflash网络文件系统,充分利用rdma的无损网络特性,并进一步发扬光大。研发出来了可以顶替EMC盘阵的存储系统,可以在其上跑Oracle等数据库系统,真的是国货之光了。 帮它们改写了一个csi的存储插件,记录一下,基于yandex的s3 csi而来,这样既可以跑到底层上提供文件块设备,也可以上升到类似NFS或者S3的层次提供文件系统,能满足大多数需求。那源代码就绝对不提供了,只说一下过程: CSI PLUGIN的使用方法: 一、导入镜像 csi存储插件的image cr.yandex/crp9ftr22d26age3hulg/csi-s3:0.42.66 文件:csi.tar 将文件放到所有worknode上,导入本地镜像库: ctr --address /run/k3s/containerd/containerd.sock -n k8s.io images import /root/csi.tar crictl -r unix:///run/k3s/containerd/containerd.sock images 看到有 cr.yandex/crp9ftr22d26age3hulg/csi-s3:0.42.66 既是导入成功 二、安装controller和nodeserver 安装driver 文件:driver.yaml kubectl apply -f driver.yaml 安装controller 文件:controller.yaml kubectl apply -f controller.yaml 安装nodeserver 文件:nodeserver.yaml 解释一下,controller是一个statefulset,整个集群运行一个即可;而nodeservershi则是一个daemonset,每个worknode都会运行一个副本 上面 worknode 是3个,所以有3个副本 三、scaleflash 块设备的使用 块设备最小单位是G,所以如果需求了100M,那也是1G。 首先必须定义一个storageclass,以后使用这一个storageclass就可以了: cat << EOF >scaleflash-storageclass.yaml --- kind: StorageClass apiVersion: storage.k8s.io/v1 metadata: name: scaleflash provisioner: ru.yandex.s3.csi parameters: mounter: scaleflash clstID: "nvmatrix_101" fsType: "xfs" EOF kubectl apply -f scaleflash-storageclass.yaml 再定义pvc ...

2025年08月07日 · 4 分钟 · 712 字 · 八戒

vault使用agent验证approle生成.env环境变量

Vault是个很厉害的 secret 引擎了,不多说了,主要用于集中管理各种密码、密钥。 用来管理Kubernetes的凭据相当好,但是我们通常是自己开发的程序,然后需要读各种配置文件,比如连接DB的用户名,密码等等,最后连接到数据库。 那么这种情况下,如果管理好配置项呢? 方法如下,用approle读取Vault的配置信息: 一、启动vault引擎测试环境 首先启动vault引擎,测试,用Docker,方便创建和销毁 # 启动容器 # 我们手动指定了ROOT_TOKEN是root,这只用于测试环境 docker run -d --rm \ --add-host host.docker.internal:host-gateway \ --cap-add=IPC_LOCK \ --name vault \ -p 8200:8200 \ -e VAULT_DEV_ROOT_TOKEN_ID=root \ -e VAULT_DEV_LISTEN_ADDRESS=0.0.0.0:8200 \ hashicorp/vault --add-host host.docker.internal:host-gateway 这个个参数的作用是在容器的 /etc/hosts 文件中添加一个主机名和 IP 地址的映射。 --add-host: 这是 docker run 的一个选项,用来在容器的 /etc/hosts 文件中添加一个自定义的主机条目。 host.docker.internal: 这是主机名。在 Docker Desktop(macOS 和 Windows)中,host.docker.internal 是一个特殊的 DNS 名称,它会被解析为宿主机的内部 IP 地址。 host-gateway: 这是 docker 在较新版本中引入的一个特殊关键字。它代表了宿主机与 Docker 网络之间的网关 IP 地址。在许多 Linux 环境中,这个关键字会指向 Docker 的网桥 IP(例如 172.17.0.1)。 综合起来,--add-host host.docker.internal:host-gateway 的作用是: ...

2025年08月06日 · 2 分钟 · 339 字 · 八戒

上难度---->内网vps用lego申请route53 DNS证书并更新到BT宝塔

上一篇我们说了 Aws的EC2服务器用lego获得免费证书并更新到ACM,这下又来了个更加有难度的挑战: DNS解析是放在了AWS Route 53上,然后vps上跑着BT宝塔,用来代理转发开发环境的https证书 这个环境如何用lego来安全的申请到证书并配置宝塔呢?这回可不像EC2那样可以自动附加IAM角色了 我们先来看看lego的用法吧: https://go-acme.github.io/lego/dns/route53/ 语法如下: 继续看,看来必须需要IAM的凭据才可以,继续下拉,有使用IAM的policy,那我们必须创建一个Role角色,然后再建立一个代理用户,gen出key,通过这个代理用户的凭据来间接进行访问 步骤如下: 一、去route53,拿到arn 我们要拿到具体域名的zone ID,就是Z0打头的那一串 二、建立IAM实际工作的Role 首先建立一个Policy,route53AcmeCert { "Version": "2012-10-17 "Statement": [ "Effect": "Allow", "Action": "route53:GetChange", "Resource": "arn:aws:route53:::change/*" }, { "Effect": "Allow", "Action": "route53:ListHostedZonesByName", }, { "Effect": "Allow", "Action": [ "route53:ListResourceRecordSets" ], "Resource": [ "arn:aws:route53:::hostedzone/Z01111111111111111111" ] }, { "Effect": "Allow", "Action": [ "route53:ChangeResourceRecordSets" ], "Resource": [ "arn:aws:route53:::hostedzone/Z01111111111111111111" ], "Condition": { "ForAllValues:StringEquals": { "route53:ChangeResourceRecordSetsNormalizedRecordNames": [ "_acme-challenge.example.com" ], "route53:ChangeResourceRecordSetsRecordTypes": [ "TXT" ] } } } ] } 然后建立一个Role,RealUpdateCertRole,绑定上面的策略 ...

2025年07月29日 · 2 分钟 · 229 字 · 八戒

Postgres的wal和PITR时间点恢复

研究了Postgres的库数据恢复和转移,再来研究一下PITR按时间点恢复 类比到MySQL,因为我们是运维,不是专业的DBA,所以恢复到正确数据即可 那跟阿里云以及自建的MySQL恢复一样,首先都要有一个每天的基础备份,然后类比MySQL的Binlog,Postgres这里就相当于wal。 这么类比就对了,那么恢复过程的思路是一样的: 首先建立一个新的实例 第二步把每天的基础物理全备给恢复上去 第三步把之后的wal日志传到新实例,恢复到指定时间点 第四步最后把表或库Dump下来,灌入到旧实例的新表或新库 那我们一步一步来解释: 一、每天建立一个基础备份,这样在Base基础上,只需恢复当天的wal,速度够快 建立每天的Base基础物理备份 pg_basebackup -Ft -Pv -Xf -z -Z5 -U postgres -h localhost -p 5432 -D /pg_backup 解释一下: -Ft: 指定备份格式为 tar。 如果使用 tar 格式,备份会输出 tar 文件,并且不需要直接访问 PostgreSQL 数据目录。 -Pv: -P:显示备份进度。 -v:启用详情模式(verbose),显示更多日志。 -Xf: -X:控制 WAL 日志的处理方式,f 表示在备份中包含 WAL 文件(Write Ahead Logs),确保备份可以用于恢复到完整的一致状态。 -z: 启用压缩功能。 -Z5: 设置压缩级别为 5(压缩级别从 0 到 9,9 为最高压缩)。 -U postgres: 使用 postgres 用户来连接数据库。 -h localhost: 指定数据库主机为当前机器(localhost)。 -p 5432: 指定 PostgreSQL 监听端口为 5432(默认端口)。 -D /pg_backup: 将备份文件保存到指定路径 /pg_backup 中。 这样我们就在 /pg_backup 中有了备份文件,包括一个backup_manifest的文件清单,以及一个压缩包 ...

2025年07月28日 · 2 分钟 · 344 字 · 八戒

单机部署kafka用kraft不依赖zookeeper

上一篇说了用Docker部署kafka,后端不用zookeeper,改用kraft。 这一篇说说不用Docker,直接单机部署kafka用kraft的方法。 一、准备,虚机的话需要4cpu 8G内存 # 装好java java --version 建3个目录 # 放kafka的2进制可执行文件 mkdir -p /opt/kafka # 放kafka的数据文件和日志文件 mkdir -p /var/lib/kafka 二、下载并配置kafka # 释放到指定目录 tar -xzf kafka_2.13-3.5.0.tgz -C /opt/kafka # 先注释掉 #broker.id=1 #zookeeper.connect=localhost:2181 # 添加/opt/kafka/config/server.properties # 9092对局域网开放,9093只用于本地单节点 process.roles=broker,controller node.id=1 controller.quorum.voters=1@localhost:9093 listeners=PLAINTEXT://0.0.0.0:9092,CONTROLLER://localhost:9093 advertised.listeners=PLAINTEXT://192.168.20.59:9092 listener.security.protocol.map=PLAINTEXT:PLAINTEXT,CONTROLLER:PLAINTEXT controller.listener.names=CONTROLLER inter.broker.listener.name=PLAINTEXT log.dirs=/var/lib/kafka/data metadata.log.dir=/var/lib/kafka/metadata # 然后需要再追加到server.properties的部分 metadata.log.dir=/var/lib/kafka/metadata num.replica.fetchers=1 offsets.topic.replication.factor=1 transaction.state.log.replication.factor=1 transaction.state.log.min.isr=1 三、初始化kafka集群 # 生成一个uuid cd /opt/kafka bin/kafka-storage.sh random-uuid # 初始化 cd /opt/kafka bin/kafka-storage.sh format -t <UUID> -c config/server.properties # 启动 bin/kafka-server-start.sh config/server.properties # 检查一下代理的状态 bin/kafka-broker-api-versions.sh --bootstrap-server localhost:9092 四、推送数据验证 ...

2025年07月28日 · 1 分钟 · 125 字 · 八戒

用Docker部署kafka且不依赖zookeeper

用redpanda居然还要每隔30天更新一下License文件,叔可忍婶不可忍啊。 换掉换掉,直接用Docker部署kafka,后端不用zookeeper,用kraft,天下苦zk也久矣! 方法很简单,用docker-compose,编辑docker-compose.yml文件 name: 'stream' services: kafka: image: confluentinc/cp-kafka:latest hostname: kafka container_name: kafka ports: - 9092:9092 - 9093:9093 environment: KAFKA_KRAFT_MODE: true # This enables KRaft mode in Kafka. KAFKA_PROCESS_ROLES: controller,broker # Kafka acts as both broker and controller. KAFKA_NODE_ID: 1 # A unique ID for this Kafka instance. KAFKA_CONTROLLER_QUORUM_VOTERS: 1@10.8.1.119:9093 # Defines the controller voters. KAFKA_LISTENERS: PLAINTEXT://0.0.0.0:9092,CONTROLLER://0.0.0.0:9093 KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: PLAINTEXT:PLAINTEXT,CONTROLLER:PLAINTEXT KAFKA_INTER_BROKER_LISTENER_NAME: PLAINTEXT KAFKA_CONTROLLER_LISTENER_NAMES: CONTROLLER KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://10.8.1.119:9092 KAFKA_LOG_DIRS: /var/lib/kafka/data # Where Kafka stores its logs. KAFKA_AUTO_CREATE_TOPICS_ENABLE: true # Kafka will automatically create topics if needed. KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR: 1 # Since we’re running one broker, one replica is enough. KAFKA_LOG_RETENTION_HOURS: 168 # Keep logs for 7 days. KAFKA_GROUP_INITIAL_REBALANCE_DELAY_MS: 0 # No delay for consumer rebalancing. CLUSTER_ID: Mk3OEYBSD34fcwNTJENDM2Qk # A unique ID for the Kafka cluster. volumes: - /var/run/docker.sock:/var/run/docker.sock - ./data:/var/lib/kafka/data # Store Kafka logs on your local machine. 注意以上的文件,暴露了2个端口,9092和9093,9092用于客户端连接,9093用于集群通讯;KAFKA_KRAFT_MODE: true用kraft不用zk. ClUSTER_ID可以换个不同的。 ...

2025年07月28日 · 2 分钟 · 245 字 · 八戒

aws的EC2服务器用lego获得免费证书并更新到ACM

交代一下背景: 公司在AWS上用的是EKS+Fargate,还有一个跳板机,证书呢就不太想用aws收费的了,干脆用免费的证书好了。 那问题就来了,Let‘s encrypt的证书90天到期,已经手动更新过3次了,实在太麻烦了,能不能自动申请并更新到ACM呢? 答案是可以的,原理是:利用EC2可以携带IAM角色的原理,就可以无凭证更新免费证书到AWS Certificate Manager了 做法如下: 一、首先去ACM中拿到证书的ARN,要确保IAM权限不外泄,避免更新错证书 二、生成一个IAM的policy,命名为AllowUpdateCertificate,只允许更新这两个特定的证书 具体策略内容如下: { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "acm:ImportCertificate" ], "Resource": [ "arn:aws:acm:ap-southeast-1:111111111111:certificate/arn01", "arn:aws:acm:ap-southeast-1:111111111111:certificate/arn02" ] } ] } 三、IAM生成一个role角色,命名为Ec2UpdateCertificateRole,把AllowUpdateCertificate策略给附上 四、到EC2的实例详细信息中,操作–>安全–>修改IAM角色 附上Ec2UpdateCertificateRole这个角色 五、在EC2的机器上,装好AWS CLI,还有lego(申请Let’s encrypt证书的软件) 先写好获得证书的脚本 get_cert.sh,域名DNS解析是托管到cloudflare的,所以也直接用API TOKEN来处理 #!/bin/bash CLOUDFLARE_DNS_API_TOKEN=######## /usr/local/bin/lego --path /usr/local/bin/certs --email zhangranrui@rendoumi.com --dns cloudflare --domains *.rendoumi.com --domains rendoumi.com renew --renew-hook="/usr/local/bin/update_aws_cert.sh" 参数--renew-hook如果有新证书,就调用后面的脚本。如果没有新证书,就无操作,避免无用功。 然后再写好 update_aws_cert.sh,这就是个千字文了,由gemini生成的: 由于lego生成的crt是证书+证书链,所以第一步要把证书部分给单独拆出来 #!/bin/bash cd /usr/local/bin/certs/certificates #首先把证书单独拆出来 awk '/-----BEGIN CERTIFICATE-----/,/-----END CERTIFICATE-----/ {print} /-----END CERTIFICATE-----/ {exit}' _.rendoumi.com.crt > _.rendoumi.com.only # --- 配置部分 --- # 您要更新的现有 ACM 证书的 ARN # 示例:CERTIFICATE_ARN="arn:aws:acm:ap-southeast-1:123456789012:certificate/abcdefab-1234-5678-abcd-1234567890ab" CERTIFICATE_ARN="arn:aws:acm:ap-southeast-1:111111111111:certificate/11111111-1111-1111-1111-111111111111" # 新证书文件的路径(例如:/opt/certs/new_certificate.crt) # 确保这个路径在您的EC2实例上是正确的 CERTIFICATE_BODY_PATH="_.rendoumi.com.only" # 新私钥文件的路径(例如:/opt/certs/private.key) # 确保这个路径在您的EC2实例上是正确的 PRIVATE_KEY_PATH="_.rendoumi.com.key" # 证书链文件的路径(可选) # 如果没有证书链,请将此变量留空或注释掉 # 示例:CERTIFICATE_CHAIN_PATH="/opt/certs/ca_bundle.crt" CERTIFICATE_CHAIN_PATH="_.rendoumi.com.issuer.crt" # 如果没有链,请将其留空 "" # ACM 证书所在的 AWS 区域 # 这个区域应该与 CERTIFICATE_ARN 中的区域匹配 # 示例:AWS_REGION="ap-southeast-1" AWS_REGION="ap-southeast-1" # --- 配置部分结束 --- echo "--- 开始使用实例角色重新导入 ACM 证书 ---" echo "证书 ARN: ${CERTIFICATE_ARN}" echo "区域: ${AWS_REGION}" # 检查文件是否存在 if [ ! -f "${CERTIFICATE_BODY_PATH}" ]; then echo "错误:证书文件 '${CERTIFICATE_BODY_PATH}' 不存在。" exit 1 fi if [ ! -f "${PRIVATE_KEY_PATH}" ]; then echo "错误:私钥文件 '${PRIVATE_KEY_PATH}' 不存在。" exit 1 fi if [ -n "${CERTIFICATE_CHAIN_PATH}" ] && [ ! -f "${CERTIFICATE_CHAIN_PATH}" ]; then echo "警告:证书链文件 '${CERTIFICATE_CHAIN_PATH}' 已指定但不存在。将不包含证书链进行导入。" CERTIFICATE_CHAIN_PATH="" # 如果文件不存在,则清空路径 fi # 构造 AWS CLI 命令。AWS CLI 会自动使用实例角色提供的凭证。 IMPORT_CMD="aws acm import-certificate \ --certificate-arn ${CERTIFICATE_ARN} \ --certificate fileb://${CERTIFICATE_BODY_PATH} \ --private-key fileb://${PRIVATE_KEY_PATH} \ --region \"${AWS_REGION}\"" # 如果有证书链,则添加到命令中 if [ -n "${CERTIFICATE_CHAIN_PATH}" ]; then IMPORT_CMD="${IMPORT_CMD} --certificate-chain fileb://${CERTIFICATE_CHAIN_PATH}" fi echo "正在执行命令:" echo "$IMPORT_CMD" echo "--------------------------" # 执行命令 # 注意:这里我们不指定 --profile 或任何凭证,AWS CLI 会自动使用实例IAM角色。 eval $IMPORT_CMD # 检查命令执行结果 if [ $? -eq 0 ]; then echo "--- 证书重新导入成功!---" echo "ACM 证书 ${CERTIFICATE_ARN} 已更新。" else echo "--- 证书重新导入失败!---" echo "请检查错误消息,确保:" echo "1. EC2 实例已正确附加了具有 acm:ImportCertificate 权限的 IAM 角色。" echo "2. 证书、私钥和链文件路径正确且可读。" echo "3. 证书/私钥/链的格式正确。" fi echo "--- 脚本执行完毕 ---" 看起来真的是又臭又长,废话连篇。注意:gemini 生成的代码有问题,aws acm import-certificate 的参数中,证书文件的前缀是fileb://,gemini给的是file://,调试了半天,最后去aws看了文档才发现。 ...

2025年07月25日 · 2 分钟 · 285 字 · 八戒

Redpanda到期后如何续License

上回我们在 Kafka的测试替代品-Redpanda 中说了怎么搭建,结果用了一个月,问题就来了 license过期了,擦的,只允许用30天,需要续费了。 方法如下: 一、打开网站,申请30天的免费license https://cloud.redpanda.com/try-enterprise 打开网站,然后填入姓名和邮箱,就会得到一个长字符串xyz,拷贝下来 二、去机器上 我们是用docker compose启动的,所以需要进入容器,导入license docker exec -it redpanda-0 /bin/sh rpk cluster license set xyz 三、重启容器 按道理上一步弄完,就应该好了的,可惜这产品做的稀烂。还必须重启容器才起作用 docker compose restart 就ok了,但是30天就更新一次license,而且必须要重启容器,这谁受得了啊。 下周就抽空装一个不依赖Zookeeper,用Rraft的Kafka来用,彻底去掉这个不伦不类的软件。

2025年07月25日 · 1 分钟 · 28 字 · 八戒

Postgres不同实例、不同用户直接的数据导出导入

公司生产环境在AWS使用了 Aurora Postgres Serveless 的数据库。 测试环境是在内网搭建了一个postgres 13数据库。 那测试和生产的实例不同,数据库不同,用户名也不同,需要把测试环境的A库的schema.public迁移到生产B库的schema.public。 普及一下概念,PG的权限分三层,数据库、schema、schema中的对象。 那么用pg_dump的话,如果不带任何参数,那会把权限也给带上,那就麻烦大了去了! 所以正确的导出、导入步骤如下: 一、首先要观察源库,看看都有什么extention,在schema.public有什么Functions 如上图所示,看到uuid_generate # 看看服务器版本 select version(); PostgreSQL 13.14 那就很奇怪,extension 只有一个plpgsql,functions却有一堆uuid_generate 那十有八九需要用到extension uuid-oosp 先去目的库建一个吧 create extension "uuid-ossp"; 二、dump数据 这里要注意,不要把任何权限的东西带进来 pg_dump -h 172.16.8.1 -U postgres -d source --schema=public --no-owner --no-privileges --file=export.sql # 全备份的命令 # export PGPASSWORD="xxxxxxxx" # pg_dump -U bbc -h localhost -p 5432 bbc > dc_system.sql 然后要编辑看看这个导入的文件 发现有create schema的语句,如果目的数据库已经有了,那需要去掉。 再看下面: 建立了一个FUNCTION,如果已经建立了extension,那也会报错,不过这2种错误我们都可以直接不用管,直接执行试试 三、导入目标库 跑一跑,看一看: psql -h 10.8.0.1 -U dest -d dest -f export.sql 报了不少错 ...

2025年07月23日 · 1 分钟 · 132 字 · 八戒