- 博客(84)
- 收藏
- 关注
原创 Linux系统编程—零拷贝
“零拷贝”指的是:不在内核态和用户态之间拷贝数据。正常情况下,拷贝一个文件的步骤是:通过 read() 读取文件:磁盘 -> 内核缓冲区 -> 用户缓冲区;通过 write() 写数据:用户缓冲区 -> 内核缓冲区 -> 磁盘。可见,数据在用户态缓冲区和内核态缓冲区之间来回拷贝了两次。使用零拷贝技术之后,数据流方向为:磁盘 -> 内核缓冲区 -> 磁盘。#define _GNU_SOURCE#include <fcntl.h>ssize_
2022-01-17 21:20:34
751
原创 AT&T 汇编
1. 基础x86 的寄存器为32位,x64 的寄存器为64位。寄存器间对应关系:64位寄存器 低32位 低16位 低8位rax eax ax alrbx ebx bx blrcx ecx cx clrdx edx dx dlrsi esi si silrdi edi di dilrbp ebp bp bplrsp esp sp splr8 r8d r8w r8br9 r9d r9w r9br10
2022-01-12 16:16:16
3460
原创 intel 汇编
1. 基础8086 CPU 的所有寄存器都是16位的。通用寄存器:ax, bx, cx, dx;为了兼容上一代 CPU,每个通用寄存器都可以分为两个8位的寄存器来使用,如,ax 可分为 ah, al,ah 为 ax 的高8位,al 为 ax 的低8位,其他寄存器类似。段寄存器:cs, ds, ss, es,分别表示代码段、数据段、栈段和附加段。8086 CPU 有20位的地址总线,可寻址1MB的内存。物理地址 = 段地址左移4位 + 偏移地址;物理地址为20位,其他均为16位。
2022-01-12 15:15:31
1028
原创 C++20 协程
1. 简介协程就是一个可以挂起执行,稍后再恢复执行的函数。协程是无栈式的(stackless),协程挂起时会返回到调用者,且恢复执行所需的数据会分开存储,而不放在栈上。只要一个函数包含 co_await、co_yield 或 co_return 关键字,则它就是协程。一个协程关联有如下多个对象:promise 对象:在协程内部操作此对象,协程通过它提交返回值或异常;协程句柄:在协程外部操作此对象,用于恢复协程的执行或销毁协程帧;协程状态:在堆上分配的内部状态。2. co_await 操
2022-01-01 16:59:01
2980
原创 Linux系统编程—信号
1. 简介信号有时也称为软件中断。一个进程能够向另一个进程发送信号,因此信号也可作为一种同步技术。传统或标准信号的编号范围是 1~31,其余信号为实时信号。 $ kill -l 1) SIGHUP 2) SIGINT 3) SIGQUIT 4) SIGILL 5) SIGTRAP 6) SIGABRT 7) SIGBUS 8) SIGFPE 9) SIGKILL 10) SIGUSR111) SIGSEGV 12) SIGUSR2 13) SIGPIPE 14) SIGALRM
2021-12-08 15:40:08
887
原创 数据结构—完全二叉堆
1. 简介完全二叉堆可用于实现优先队列。当然,使用数组或列表也可以实现优先队列,但通常需要先将其中的所有数据进行排序才可,即首先维护一种全序关系。但事实上,优先队列只要能够确定全局优先级最高的 entry 即可,而不要求全局先有序。完全二叉堆无需先对所有数据进行排序即可确定全局优先级最高的 entry,因此更加适用于优先队列的实现。2. 定义完全二叉堆的逻辑结构就是一棵完全二叉树,但堆可以使用数组来实现。对于最小堆来说,堆中每个父节点都要小于等于其子节点;对于最大堆
2021-12-07 23:25:51
417
原创 数据结构—跳跃表
1. 简介对于数组来说:如果数组是有序的,则搜索操作可以使用二分搜索法,其时间复杂度为 O(logn)O(\log n)O(logn);但插入和删除操作的时间复杂度则需要 O(n)O(n)O(n)。对于链表来说:即使链表是有序的,其搜索操作也无法使用二分搜索法,只能进行顺序查找,时间复杂度为 O(n)O(n)O(n);但其插入和删除操作具有 O(1)O(1)O(1) 的时间复杂度。为了兼顾搜索、插入和删除操作的效率,平衡搜索树被提出。但无论是 AVL 树还是红黑树,其实现都较为复杂。
2021-12-07 09:19:58
1225
原创 数据结构—红黑树
1. 简介AVL 树在删除节点之后可能需要多达 O(logn)O(\log n)O(logn) 次的旋转才能够使整棵树恢复平衡,但也因此导致了全树拓扑结构频繁地发生大幅度的变化。红黑树主要是针对上述不足所做的改进,它也是一棵平衡二叉搜索树,且可以保证每次插入、删除操作之后的重平衡过程中,全树拓扑结构的更新仅涉及常数个节点。红黑树的搜索、插入和删除操作的时间复杂度也为 O(logn)O(\log n)O(logn)。2. 约束红黑树具有如下约束:(1)每个节点要么为红色,要么为黑色;(2)树
2021-12-05 17:31:29
651
原创 数据结构—AVL树
1. 约束对于节点 vvv,我们定义其平衡因子为:vvv 的左、右子树的高度差。AVL 树是一棵二叉搜索树,但其引入了额外的约束:树中各节点的平衡因子的绝对值不得超过 111。设一共有 nnn 个节点,AVL 树始终可以将树的高度控制在 O(logn)O(\log n)O(logn) 以内,且每次搜索、插入和删除操作均可在 O(logn)O(\log n)O(logn) 时间内完成。2. 插入往 AVL 树中插入新节点可能会增加树的高度,从而导致其所在的子树失衡。(1)首先按
2021-12-05 12:04:20
490
原创 数据结构—B+树
1. 约束B+ 树的约束与 B 树类似,一棵 mmm 阶 B+ 树具有如下特点:(1)根节点约束:根节点要么是一个叶节点,要么至少具有两个孩子节点;(2)内部节点约束:除根节点以外,每个内部节点都具有 [⌈m/2⌉,m][\lceil m/2\rceil, m][⌈m/2⌉,m] 个孩子节点,因此具有 [⌈m/2⌉−1,m−1][\lceil m/2\rceil -1, m-1][⌈m/2⌉−1,m−1] 个关键码;(有些定义中,要求关键码个数与指针个数相同)(3)叶节点约束:所有叶节点都处在树的同
2021-12-04 16:15:48
849
原创 数据结构—B树
1. 简介如果数据太多导致内存装不下,则必须把数据结构存放到磁盘上,此时大 OOO 模型不再适用。磁盘的访问代价相比于 CPU 计算和内存访问来说实在是太高了,因此宁愿执行大量的计算,也要减少磁盘 I/O。不平衡二叉树在最坏的情况下具有线性的深度,因此如果将其作为一种磁盘数据结构,则最坏情况下仍需进行大量的磁盘 I/O。2. 约束一棵 mmm 阶 B 树具有如下特点:(1)根节点约束:根节点要么是一个叶节点,要么至少具有两个孩子节点;(2)内部节点约束:除根节点以外,每个内部节点都具有 [
2021-12-04 14:34:23
321
原创 一致性哈希算法
1. 传统的哈希算法假设存储集群中一共有 mmm 个节点,且已使用 0,1,..,m−10,1,..,m-10,1,..,m−1 进行编号,现要将对象 ooo 存到集群上。如果使用传统的哈希算法来确定 ooo 的存储位置,则 ooo 应存储在编号为 hash(o.id)%m\text{hash}(o.id)\%mhash(o.id)%m 的节点上。(o.ido.ido.id 表示对象 ooo 的 ID)传统哈希算法的不足是可扩展性差,当集群增删节点时,mmm 便会改变,所有数据的存储位置都得重新计算,
2021-12-03 18:08:14
1000
原创 CRUSH 算法
1. 简介CRUSH 算法能够根据每个存储设备的权重来分布数据对象,使得这个分布近似于均匀分布。数据分布是由具有层级结构的 cluster map 来控制的,其表示了可用的存储资源,以及一些逻辑元素。数据分布策略是根据放置规则来定义的,其指定了要从集群中选出多少个存储设备以存储数据副本,以及数据副本的存放限制(如,故障域隔离)。输入一个整数 xxx(通常是对象的 ID),CRUSH 算法会输出一个大小为 nnn 的有序列表 R→\mathop{R} \limits ^{\righta
2021-12-03 11:11:57
2783
原创 Go 同步机制
1. 互斥量import "sync"var mutex sync.Mutexmutex.Lock()// ...mutex.Unlock()2. 读写锁import "sync"var mutex sync.RWMutex读者:mutex.RLock()// ...mutex.RUnlock()写者:mutex.Lock()// ...mutex.Unlock()3. 条件变量import "sync"var mutex sync.Mutexvar
2021-12-01 20:21:18
297
原创 Raft 算法—集群配置变更、Log压缩、客户端交互
1. 配置变更集群的配置会包含在 log entries (使用特殊的 entries)中,并复制到其他节点上。设集群的旧配置为 ColdC_{old}Cold,新配置为 CnewC_{new}Cnew(如,CnewC_{new}Cnew 中添加或移除了某些节点)。Raft 在新旧配置之间引入了一个中间状态,称为 joint consensus,其包含了新旧配置,即其配置为 Cold,newC_{old,new}Cold,new,也就是说,此阶段的集群成员为 ColdC_{old}Cold
2021-12-01 11:34:17
298
原创 Raft 算法—Leader选举、Log复制
1. 复制状态机(1)客户端向服务器发送一条命令;(2)服务器上的共识模块将接收到的命令添加到自己的 log 中,然后和其他服务器上的共识模块通信,以复制该命令到其他服务器上;(3)一旦命令被成功复制到大多数服务器上之后,每个服务器上的状态机将按序执行 log 中的命令;(4)状态机输出并返回命令的执行结果。2. Raft基础集群角色Raft 集群中的节点按角色可划分为:leader、follower 和 candidate。(1)正常情况下,集群中只存在一个 leader,并由 leade
2021-11-30 22:05:34
1584
原创 Ceph架构
1. 简介Ceph 能够同时提供对象存储、块存储和文件存储。(1)对象存储提供 RESTful 接口;提供与 S3 和 Swift 兼容的 API;对象条带化;多站点部署和复制;(2)块存储精简配置,即能够按需分配;镜像最大可达16EB;可配置条带化;内存缓存;快照;写时复制的克隆;支持 KVM 和 libvirt;内核驱动程序支持;灾难恢复;(3)文件存储提供与 POSIX 兼容的语义;数据与元数据分离;可配置条带化;内核驱动程序支持;子目录快照;
2021-11-29 20:29:16
483
原创 Ceph问题及解决办法
问题1创建存储池之后出现 100.000% pgs not active,导致后续 rbd 命令执行时卡住不返回?解决办法:cd /etc/ceph/ceph osd getcrushmap -o /etc/ceph/crushmapcrushtool -d /etc/ceph/crushmap -o /etc/ceph/crushmap.txtsed -i 's/step chooseleaf firstn 0 type host/step chooseleaf firstn 0 type o
2021-11-28 10:51:21
841
原创 Ceph基本操作—存储池、块设备
1. 存储池创建存储池:$ ceph osd pool create data-pool 8 8pool 'data-pool' created列出存储池:$ ceph osd pool lsdata-pool设置/获取对象副本数:$ ceph osd pool set data-pool size 1set pool 1 size to 1$ ceph osd pool get data-pool sizesize: 1查看存储池的统计信息:$ rados dfPOOL
2021-11-28 10:50:10
2145
原创 Ceph单节点安装
1. 前置配置(1)配置主机名ceph0X 主机上:hostnamectl set-hostname ceph0XX 为具体的主机编号,如,1、2…。在所有节点上配置主机名解析:192.168.122.132 ceph01192.168.122.181 ceph02(2)关闭firewal和selinuxsystemctl stop firewalld && systemctl disable firewalldsetenforce 0(3)配置免密登录配置
2021-11-28 09:28:43
774
原创 Linux用户管理—新增管理员
新增 cephadm 用户,其登录密码为 cephadm,并将其设为管理员:useradd cephadmecho 'cephadm' | passwd --stdin cephadm echo "cephadm ALL = (root) NOPASSWD:ALL" | sudo tee /etc/sudoers.d/cephadmchmod 0440 /etc/sudoers.d/cephadm
2021-11-27 16:49:39
323
原创 Linux 远程桌面
yum install -y epel-releaseyum install -y xrdp tigervnc-serversystemctl start xrdp之后在 Windows 上即可通过 mstsc 远程连接 Linux。
2021-11-27 15:03:26
422
原创 Linux系统编程—目录
1. 创建目录#include <sys/stat.h>#include <sys/types.h>int mkdir(const char *pathname, mode_t mode);创建路径为 pathname 的目录,其访问权限为 mode;注意,mkdir() 创建的只是路径名中的最后一部分,它并不会自动创建缺失的父目录。成功时返回 0,失败时返回 -1。如果指定的目录已经存在,则失败返回,并将 errno 设为 EEXIST。2. 删除目录#in
2021-11-20 19:36:49
801
原创 MySQL概览
1. MySQL 架构MySQL 包括:连接池组件、管理服务和工具组件、SQL接口组件、查询分析器组件、优化器组件、缓冲组件、插件式的存储引擎、物理文件。2. 存储引擎可使用 show engines; 命令来查看支持的存储引擎。(1)InnoDB支持事务;支持外键;支持哈希索引和 B-Tree 索引;行锁设计;非锁定读,即默认读取操作不会产生锁;使用多版本并发控制来获得高并发性;使用 next-key locking 策略来避免幻读;每张表的存储都是按照主键的顺序进行存放的;
2021-11-20 11:28:58
901
原创 Go Web—gin框架
1. Hello, World!package mainimport ( "github.com/gin-gonic/gin" "net/http")type HelloController struct {}func (controller *HelloController) Hello (ctx *gin.Context) { ctx.String(http.StatusOK, "Hello, World!")}func main() { controller := &am
2021-11-13 23:24:19
320
原创 Linux系统编程—记录锁
1. 简介使用 fcntl() 能够在一个文件的任意一个部分上放置一把锁,这个文件部分既可以是一个字节范围,也可以是整个文件。2. API#include <unistd.h>#include <fcntl.h>int fcntl(int fd, int cmd, ... /* arg */ );使用 fcntl() 操作记录锁时,cmd 可以取值如下:F_SETLK:设置锁,可以是加锁或解锁,取决于 arg 参数;如果无法立马加锁,则 fcntl() 会立马返回
2021-11-13 11:24:26
1194
原创 Python openpyxl库
1. 读写单元格from openpyxl import load_workbookwb = load_workbook('tmp.xlsx')# 获取活动的表单sheet = wb.active# 读取第三行第一列的值,行和列都是从1开始计数的。value = sheet.cell(row=3, column=1).valueprint(value)# 写入第三行第七列sheet.cell(row=3, column=7).value = 123wb.save('tmp.xl
2021-11-12 22:44:10
727
1
原创 Linux系统编程—epoll
1. 简介epoll 的优点:当检查大量的文件描述符时,epoll 的性能比 select() 和 poll() 的要高。epoll 既支持水平触发也支持边缘触发,select() 和 poll() 只支持水平触发。epoll 的缺点:epoll 是 Linux 特有的,不可移植。2. 函数原型...
2021-11-12 21:12:11
1650
原创 Linux系统编程—select
1. 函数原型#include <sys/select.h>#include <sys/time.h>#include <sys/types.h>#include <unistd.h>int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout);保持阻塞,直到一个或多个文件描述符集合就绪、或超时。超
2021-11-11 20:59:44
1082
原创 Go 类型系统
1. 类型别名type Alias = Type此后,在 Alias 的作用域内,Alias 就是 Type 的别名。如,type Second = uint32var t1 Second = 10var t2 uint32 = 20var t3 = t1 + t22. 类型定义type NewType TypeNewType 是一个新的类型,称为 defined type,它不同于任何类型,包括 Type。如,type Second uint32var t1 Second =
2021-11-11 15:58:05
316
原创 Linux系统编程—文件
1. 文件描述符文件描述符就是一个非负整数,用于充当文件句柄,以表示一个打开的文件。标准文件描述符标准输入(0):STDIN_FILENO标准输出(1):STDOUT_FILENO标准错误(2):STDERR_FILENO2. 文件操作#include <sys/types.h>#include <sys/stat.h>#include <fcntl.h>int open(const char *pathname, int flags);int
2021-10-31 11:45:51
256
原创 Kubernetes Service
1. 简介Service 的背后是一个拥有相同标签的 Pod 集合,且这些 Pod 都提供着相同的功能。Kubernetes 为每个 Pod 都赋予了一个唯一的 IP 地址,因为 Pod 可以动态地销毁和重建,故而其 IP 地址也是动态变化的。不同于 Pod,Kubernetes 为 Service 赋予了一个 DNS 名称,且 Service 不会动态地销毁和重建,故而在其生命周期内,其对应的 IP 地址是不会改变的。Service 为我们提供了一种服务发现机制,通过访问 Service 的 DNS
2021-10-24 10:14:49
91
原创 Kubernetes Deployment
1. 简介Deployment 背后管理着一个或多个 ReplicaSet,并通过 ReplicaSet 来管理着一组 Pod。与 ReplicaSet 不同,Deployment 可以实现滚动更新的功能,即创建一个新的 ReplicaSet。此外,Deployment 也支持回滚,即启用旧的 ReplicaSet。2. 用法deploy.yaml:apiVersion: apps/v1kind: Deploymentmetadata: name: nginx-deploymentspe
2021-10-23 14:53:22
116
原创 使用 HTTP 拉取 Docker 镜像
此处以从镜像仓库 https://fl791z1h.mirror.aliyuncs.com/ 中拉取 busybox 镜像为例。首先获取镜像的 manifests 信息:$ curl -kL https://fl791z1h.mirror.aliyuncs.com/v2/library/busybox/manifests/latest{ "schemaVersion": 1, "name": "library/busybox", "tag": "latest", "archit
2021-10-22 10:50:04
1638
原创 Kubernetes Pod
1. 简介Pod 是一个容器集合,且集合中的容器运行于同一台主机上。同一个 Pod 中的多个容器共享相同的存储资源和网络资源。Pod 是 Kubernetes 中最小的调度单元。2. 基础用法在线测试平台:minikubepod.yaml:apiVersion: v1kind: Podmetadata: name: nginx labels: app: nginx version: devspec: containers: - name: nginx
2021-10-21 21:26:36
108
原创 搭建gitlab代码仓库
1. 安装系统:CentOS7其他操作系统对应的安装包见 https://mirrors.tuna.tsinghua.edu.cn/gitlab-ce/$ wget https://mirrors.tuna.tsinghua.edu.cn/gitlab-ce/yum/el7/gitlab-ce-12.8.6-ce.0.el7.x86_64.rpm --no-check-certificate$ sudo yum install -y gitlab-ce-12.8.6-ce.0.el7.x86_64.
2021-10-16 16:37:44
199
原创 MongoDB基本操作
1. 安装创建 /etc/yum.repos.d/mongodb-org-5.0.repo 文件:[mongodb-org-5.0]name=MongoDB Repositorybaseurl=https://repo.mongodb.org/yum/redhat/$releasever/mongodb-org/5.0/x86_64/gpgcheck=1enabled=1gpgkey=https://www.mongodb.org/static/pgp/server-5.0.asc$ su
2021-10-13 10:08:42
193
原创 cmake使用
1. C/C++程序编译过程C/C++程序的编译过程包括四个部分:预处理:包括头文件、扩展宏;编译:检查语法,生成汇编代码;汇编:将汇编代码转换为机器码,生成目标文件;链接:合并多个目标文件及所需的静态库文件、或包含动态库调用信息,生成可执行文件。源程序:#include <iostream>using namespace std;int main(){ cout << "hello, world!\n"; return 0;}预处理:[min
2021-10-06 21:52:54
162
原创 Docker常用命令
1. 操作容器run$ docker run [OPTIONS] IMAGE[:TAG|@DIGEST] [COMMAND] [ARG...]使用指定的镜像来运行容器,并可选地在容器中运行指定的命令。分离模式:通过 -d 选项指定;容器会在任务(进程)结束时退出。前台模式:可以将控制台连接到容器中进程的标准输入、输出、错误;通过 -t 选项可以为其分配一个伪终端;通过 -i 选项可以保持标准输入处于打开状态。--rm 选项能够在容器退出时自动删除容器。[ming@localhost ~]$
2021-10-06 15:40:20
244
原创 Dockerfile使用
在 Docker 中,可以通过 docker build 命令和 Dockerfile 文件来构造自己的 Docker 镜像。注意,docker build 命令会递归地将构建整个上下文(如,某个本地目录)发送给 docker daemon,所以不要将根目录 / 作为构建上下文。1. FROMFROM 指令用于初始化一个新的构建阶段,并为后续指令指定一个基础镜像。FROM [--platform=<platform>] <image>[:<tag>] [AS &l
2021-10-04 20:07:41
419
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人