JuiceFS 编译与安装
本文不介绍 JuiceFS ,不了解的朋友可以看一下官网,或我写过的 JuiceFS 单机模式初体验。
1. 编译目标如果你有使用过 JuiceFS 或看过相关文档,就会知道 JuiceFS 实际上只有一个二进制文件,用起来相当简单。
所以我们的编译目标也很简单了,就是编译得到一个二进制可执行文件。
2. 下载 JuiceFS 源码我这里还是先创建一个空文件夹,并在这里面进行后续操作(个人习惯):
1mkdir juicefs-compile && cd juicefs-compile
然后克隆 JuiceFS 源码:
1git clone https://github.com/juicedata/juicefs.git
3. 安装依赖JuiceFS 的依赖主要有两个:Golang 1.18+ 和 GCC 5.4+,如果你的环境里已经有了这两个依赖,则可以跳过这小节。
可以使用 go version 和 gcc -v 两个命令检查以下。
3.1. 简单安装的方式最简单的安装方式就是 yum 直接安装,我这里 yum 内提供的版本是 Golang 1.18.10 和 G ...
(CentOS/RedHat 系)Linux 安装最新版 GCC
1. 准备因为编译 GCC 源码的时候是需要 GCC 的,并且支持 C++ 11,所以我们得确保系统里当前是存在 GCC 的,如果没有的话,先安装一个:
1sudo yum install gcc-c++
yum 中提供的 GCC 版本是 8.5.0,是满足我们编译最新版 GCC 源码的要求的。
也就是说,我们所谓的安装最新版 GCC,其实是升级现有的 GCC 到最新版。
另外 GCC 的编译耗时可能非常长(也取决你的配置),如果你是着急用的话,可能不太行。
2. 下载最新版 GCChttps://ftp.gnu.org/gnu/gcc/ 中可以看到全部的 GCC 版本,找到你需要的版本的文件夹,进入,里面名字形如 gcc-12.2.0.tar.gz 就是我们需要的(一般也是 Size 最大的那个)。
我这里是找到最新版 GCC,即 12.2.0。
3. 编译安装我一般喜欢在一个干净的文件夹内做一件事情(个人习惯):
1mkdir ~/gcc-install && cd ~/gcc-install
下面进入正题。
下载 tar 包并解压:
123wget https: ...
(CentOS/RedHat 系)Linux 安装最新版 Golang
在 https://go.dev/dl/ 页面可以看到 Golang 目前的最新版本,编辑此文章时是 1.20.3。
我们找到所需要的版本,我这里的环境是 x86_64 架构上的 AlmaLinux,所以需要的版本是:
go1.20.3.linux-amd64.tar.gz
如果你和我环境类似,也是 x86_64 架构上的红帽系 Linux,那么你应该选择和我一样的版本(最多版本号不一样。
我个人比较喜欢在一个干净的文件夹内做一件事,所以:
1mkdir ~/golang_install && cd ~/golang_install
下载我们需要的 Golang 版本 tar 包:
1wget https://go.dev/dl/go1.20.3.linux-amd64.tar.gz
删除机器上现有的 Golang,并将刚刚的 tar 包解压到 /usr/local/go/:
12rm -rf /usr/local/gotar -C /usr/local -xzf go1.20.3.linux-amd64.tar.gz
配置环境变量,打开 /etc/profile:
1 ...
JuiceFS 单机模式初体验
本文不涉及分布式系统,仅在单机模式下简单体验 JuiceFS。
1. 什么是 JuiceFS ?JuiceFS 是一款面向云原生设计的高性能分布式文件系统。
JuiceFS 是跨平台的,可以在几乎所有主流架构上的各种操作系统中运行,包括且不限于 Linux、macOS、Windows。
JuiceFS 采用「数据」与「元数据」分离存储的架构,从而实现文件系统的分布式设计。
JuiceFS 中文件数据本身会被切分保存在对象存储(例如 Amazon S3),而元数据则可以保存在 Redis、MySQL、TiKV、SQLite 等多种数据库中。
JuiceFS 在 GitHub 上开源,开源协议为 Apache 2.0。
此小节介绍内容节选自 JucieFS 官方文档。
2. 安装 JuiceFS 客户端JuiceFS 客户端只有一个二进制文件,我们可以下载官方预编译的版本直接使用,也可以用源代码手动编译。
我这里直接使用官方预编译的二进制文件。如果你想自己编译,可以看 JuiceFS 编译与安装,最终都是得到一个二进制文件。
本文在 x86_64 架构上的 AlmaLinux 8.7 中进 ...
配置 VMware 虚拟机为开发机
1. 我为什么选择虚拟机做开发机我的开发机最终选择是在 VMware 上的 Linux 虚拟机。
我个人采用这样的开发方式,很大原因是非常喜欢这种模式的便捷性。
VMware 是跨平台的,我们的虚拟机可以直接通过 U 盘拷走,随处安置。
虚拟机可以随时制作快照,备份、回滚非常简单,完全不用担心把环境搞坏了。
关于这个开发模式,我自己也是初次使用,后面如果遇到哪些问题,或者有哪些新的心得,我也会更新到这篇文章里 ~
2. 镜像安装我选择装在虚拟机中的 Linux 发行版及版本是 AlmaLinux-8.7-x86_64-minimal。
线上生产环境是 CentOS 7.3,但是公司电脑与我家里电脑的 CPU 比较新,无法通过 CentOS 7.x 的硬件检测。
所以在开发机上,与其装已经不再维护的 CentOS 8.x,不如用 AlmaLinux 了。
这里没有选择最新的 AlmaLinux 版本,而是选择了 8.7(截止写此文章时,最新版本为 9.1),主要是为了规避过新版本的潜在风险。
镜像下载地址:AlmaLinux-8.7-x86_64-minimal.iso
Vmwa ...
笔记 - 关于《Effective C++》 中的 55 个做法
最近闲来无事,想起了之前买的《Effective C++(第三版)》这本书,就打算看一下。
书中介绍了改善程序与设计的 55 个具体做法,但本文并不会像书中那样对相关问题进行分析,而是直接给出结论和重点(个别也会简单解释)。
如果你在阅读此文章,那么我认为,在大部分场景下,你可以直接采用这些结论,因为不满足这些结论的情况是比较少的。但如果你有时间,还是建议阅读原书,理解这些结论从何而来,以及在哪些情况下可能不适用。
另外,由于我读此书时已经是 2023 年,C++ 标准已经到了 23,而此书是依据 98/03 标准编写的,所以本文中我会将部分过时内容替换为新内容。我替换了的部分会在对应位置做出标注或解释。
下面的笔记顺序,与原书的结构顺序一致,每个做法称为一个“条款”。
1. 让自己习惯 C++条款 01:将 C++ 视为一个语言联邦
C++ 高效编程守则视状况而变化,取决于你使用 C++ 的哪一部分。
作者认为 C++ 可以视为一个由相关语言组成的联邦,而非单一语言。在其某个次语言(sublanguage)中,各种守则与通例都倾向简单、直观易懂、并且容易记住。当我们由一个次语言换 ...
C/C++ 程序编译过程简述
C/C++ 程序最简单的 “Hello World” 几乎是每个程序员闭着眼睛就能写出的,编译运行过程一气呵成,基本成了程序入门和开发环境测试的默认标准。
例如,一个最基本的 “Hello World” 的 C 语言程序像下面这样:
123456#include <stdio.h>int main() { printf("Hello World\n"); return 0;}
在 Linux 中,当我们使用 GCC 来编译此程序时,只需要使用最简单的命令(假设源文件名为 hello.c):
123$ gcc hello.c$ ./a.outHello World
事实上,上述过程可以分解为 4 个步骤,分别是预处理(Prepressing) 、编译(Compilation) 、汇编(Assembly) 和链接(Linking),如下图所示:
1. 预编译首先是源代码文件 hello.c 和相关的头文件,如 stdio.h 等被预编译器 cpp (这里预编译器的名字就叫 “cpp”,下面示例中也使用了这个命令)预编译成一个 ...
C++ 完美转发
1. 什么是完美转发?提到完美转发,就有必要先说一下,什么是转发,什么样的转发才称得上是完美转发。
在 C++ 中,转发指的就是函数之间的参数传递(例如函数 f1 接收了一个参数 a,而后又将此参数 a 传递给了其函数体内调用的另一个函数 f2)。
而完美转发指的就是在函数之间传递参数的过程中,参数在传递后的属性保持不变(如左值仍是左值,右值仍是右值,const 修饰也会保留)。
2. 常规转发存在的问题对于普通的转发,参数在函数间传递时属性可能会发生改变,我们看一个例子。
12345678910111213141516171819202122232425#include <iostream>#include <utility>void an_orther_fun(int a, int& b){ std::cout << "in an_orther_fun(): a = " << a << ", b = " << ++b << std::e ...
C++ std::move() 实现详解
本文不介绍 std::move() 的功能与用法,有了解需要可参考 std::move - cppreference.com。
本文主要研究 std::move() 的实现原理,从其定义出发,自顶向下剖析。
1. std::move() 的定义移动函数 std::move() 定义在头文件 <utility> 中。
下面的定义取自 GCC 源码:
123456789/** * @brief Convert a value to an rvalue. * @param __t A thing of arbitrary type. * @return The parameter cast to an rvalue-reference to allow moving it.*/template<typename _Tp> constexpr typename std::remove_reference<_Tp>::type&& move(_Tp&& __t) noexcept { return s ...
C++ 内存模型和原子操作
C++ 新标准引入了不少新特性,其中一项非常重要,它既不是新的语法功能,也不是新的程序库工具,而是新的线程感知的内存模型,却被大多数程序员所忽略。内存模型精确定义了基础构建单元应当如何运转。唯有以内存模型为基石,C++ 提供的并发工具方能可靠的工作。多数程序员之所以会忽略内存模型,是因为我们只需要借助互斥保护数据,并采用条件变量、future、线程闩或线程卡来触发事件信号,就足以将多线程运用自如,结果甚少有人深究底层细节。只有当我们尽力“贴近计算机底层硬件”,内存模型的精确细节的重要作用才会彰显。
不论其他语言如何定位,C++ 都是操作系统级别的编程语言。C++ 标准委员会的一个目标是领 C++ 尽量贴近计算机底层,而不必改用其他更低级的语言,C++ 十分灵活,可满足程序员的许多需求,包括容许他们在必要时“贴近计算机底层硬件”,语言本身不应构成障碍。原子类型(atomic)及其操作应运而生,提供了底层同步操作的功能,其常常只需一两条 CPU 指令即可实现。
1. 内存模型基础内存模型牵涉两个方面:基本结构和并发。基本结构关系到整个程序在内存中的布局。它对并发很重要,尤其是在我们分析 ...