当前位置: 首页 > 编程日记 > 正文

如何用 ndctl/ipmctl 管理工具 配置不同访问模式的pmem设备

文章目录

    • 1 PMEM 底层架构
    • 2 PMEM 逻辑架构
    • 3 ipmctl 创建 不同模式的 region
      • 3.1 安装
      • 3.2 创建AppDirect mode的region
      • 3.3 创建 Memory Mode模式
      • 3.4 创建 混合模式
      • 3.5 查看创建的结果
    • 4 ndctl 创建不同类型的 namespaces
      • 4.1 安装
      • 4.2 创建/删除 一个任意类型的namespace
      • 4.3 指定类型 创建 namespaces
      • 4.4 变更已有namespace 类型
    • 5 namespace 的应用
    • 6 fio测试 fsdax 和 devdax
    • 7 参考

之前总结过一篇文章来总体介绍optane 持久内存 的架构以及其 编程模式 Intel Optane 持久内存概览,这里主要是记录一下针对Optane 持久内存 管理工具的使用方式,通过这一些工具的使用能够更为清晰得了解NVM(pmem) 的底层架构。

下文中提到的创建命令都是在 centos上进行的,不过ipmctl/ndctl/fio 这种基础命令使用方式都是一样的,可能就是安装这一些工具的命令和其他的系统有一些差异。

1 PMEM 底层架构

PMEM 的存储介质是 3D Xpoint ,其底层存储单元是PCM(phase change memory 即相变内存),这也是pmem 物理存储和传统的 NAND SSD最大的差异。但其和Optane NVMe SSD 最大的差异则是物理接口的不同,一个是PCIe接口(nvme ssd),一个是DIMM 接口(pmem)。 关于 NAND和3D XPoint 的物理差异可以通过从NMOS 和 PCM 底层存储单元 来看NAND和3D XPoint的本质区别 来了解一下。

那我们先看看 PMEM 的底层物理形态,这是我们的NUMA 下的cpu和内存插槽的分布。在这里插入图片描述
其中蓝色区域是DRAM 插槽,黑色插槽可以插PMEM 存储介质。
需要注意的是:

  1. 对于每一个CPU而言,PMEM 介质应该插在每组(一蓝一黑两个算一组)靠近CPU的那一个槽中,即黑色的插槽;另一个槽插入DRAM。
  2. 使用App Direct Mode 的时候每组槽中的PMEM 可以不搭配DRAM;使用Memory Mode 的时候,每组槽中的PMEM必须搭配DRAM,否则无法配置成MemoryMode 模式使用。
  3. 必须要确保每个CPU两边的 pmem 介质个数相等;而不同组 CPU 各自的PMEM数量可以不同,造成的结果就是两个region 显示的容量不同。

查看当前系统DRAM 和 pmem 的拓扑结构

# 需要root 用户执行
$ ipmctl show -topologyDimmID | MemoryType | Capacity | PhysicalID| DeviceLocator
================================================================================0x0001 | Logical Non-Volatile Device | 126.375 GiB | 0x0021 | DIMM 60x0011 | Logical Non-Volatile Device | 126.375 GiB | 0x0023 | DIMM 40x0101 | Logical Non-Volatile Device | 126.375 GiB | 0x0027 | DIMM 70x0111 | Logical Non-Volatile Device | 126.375 GiB | 0x0029 | DIMM 90x1001 | Logical Non-Volatile Device | 126.375 GiB | 0x002d | DIMM 180x1011 | Logical Non-Volatile Device | 126.375 GiB | 0x002f | DIMM 160x1101 | Logical Non-Volatile Device | 126.375 GiB | 0x0033 | DIMM 190x1111 | Logical Non-Volatile Device | 126.375 GiB | 0x0035 | DIMM 21N/A | DDR4 | 32.000 GiB | 0x0020 | DIMM 5N/A | DDR4 | 32.000 GiB | 0x0022 | DIMM 3N/A | DDR4 | 32.000 GiB | 0x0024 | DIMM 1N/A | DDR4 | 32.000 GiB | 0x0026 | DIMM 8N/A | DDR4 | 32.000 GiB | 0x0028 | DIMM 10N/A | DDR4 | 32.000 GiB | 0x002a | DIMM 12N/A | DDR4 | 32.000 GiB | 0x002c | DIMM 17N/A | DDR4 | 32.000 GiB | 0x002e | DIMM 15N/A | DDR4 | 32.000 GiB | 0x0030 | DIMM 13N/A | DDR4 | 32.000 GiB | 0x0032 | DIMM 20N/A | DDR4 | 32.000 GiB | 0x0034 | DIMM 22N/A | DDR4 | 32.000 GiB | 0x0036 | DIMM 24

2 PMEM 逻辑架构

这里介绍两种 用于组织插在DIMM 插槽之上的逻辑分离存储形态 regionnamespace

  • region : 用来组织pmem module的逻辑概念。一个region 中可以有一个或者多个pmem module(插在DIMM 上的pmem 存储介质)。当前支持的region 模式有两种: interleave 和 non-interleave 的;其中interleave 模式是一个region 可以跨当前CPU的多个 DIMM,non-interleave 模式则是一个region 只能在一个DIMM 上。
  • namespace: 是一段 on pmem 的 可连续寻址的地址范围,类似于硬盘分区 或者 SCSI的逻辑单元(LUN) 或者 NVMe 的namespace。只有在 创建的region 模式是 AppDirect 模式时才能在region 上创建namespace。

除了以上两个主要的 对pmem 操作的逻辑分区之外,还有几个概念需要了解:

  • Label : 每一个pmem module(pmem 存储介质) 都包涵一个 Label Storage Area(LBA) 区域,用来存储namespace 的元数据配置。这样,就可以在region 上创建不同类型的namespace 来支持针对pmem 的不同访问模式。
  • DAX:Direct Access。pmem 在AppDirect 模式下 通过namespace 创建的 不同类型的设备可以为用户提供 device access 以及 fs access的访问模式。在fs access 下 通过支持DAX 模式的文件系统(xfs, ext4, on windows ntfs)来 最大程度得缩短访问pmem的路径,访问的过程都是通过mmap 来进行的,能够by-pass page-cache, i/o subsystem 以及 中断和上下文切换。

下面是 non-interleaved regions 和 interleaved region 以及 on interleave region下的namespaces。
在这里插入图片描述
关于pmem 编程架构形态如下:
在这里插入图片描述
其中namespace 支持的四种模式 可以匹配到上面针对 NVM-DIMMS 的访问形态中了:

  1. raw: 就是一个内存盘的形态来直接访问,不支持DAX 模式的访问。
  2. sector: 可以作为一个传统的块设备 以及 on 块设备的文件系统,且这个文件系统不限制类型(任意文件系,不需要dax支持)。可以允许按字节访问,但是不能保证访问的原子性。
  3. fsdax: 需要 pmem-aware filter system支持,即支持dax 挂载的文件系统,这样该namespace 可以通过标准文件接口读写 ,同时也支持 通过pmdk 来访问。这个namespace 类型 是大多数的appdirect 模式下的持久内存使用方式。
  4. devdax: 允许通过 mmap 直接将指定容量的 pmem 介质映射到内存进行访问,这个devdax 模式的namespace 被创建出来之后不能像其他的块设备一样创建dax文件系统,它被映射出来之后是一个字符设备形态(/dev/dax3.0 这种)。这种模式一般用作虚拟机,RDMA 以及 大页映射。

到此,我们大体就清楚了PMEM 的逻辑架构 ,如何通过 逻辑 region 组织物理上的 DIMMS,以及如何在逻辑region之上构建数据分离存储的namespaces。

接下来我们看看如果通过 pmem的 management tools 来组合这一些逻辑架构,构建丰富的pmem 使用形态。

3 ipmctl 创建 不同模式的 region

如果你的环境中已经有了pmem设备(直接可用的文件系统形态的pmem),可以直接跳过这一个工具的介绍,看下一个 ndctl工具。

3.1 安装

这个工具是构建pmem region的底层工具,建议安装的时候让其版本在2.x 及以上。
直接源码编译安装即可:

git clone https://github.com/pmem/ndctl.git
cd ndctl
./autogen.sh
./configure CFLAGS='-g -O2' --prefix=/usr --sysconfdir=/etc --libdir=/usr/lib64
make
make check
sudo make install

安装完成之后记得更新一下PATH,否则命令行会找不到这个工具export PATH=$PATH:/usr/local/bin

需要注意一个问题,就是如果你的ipmctl 最开始的版本比较低,可能会导致最后创建的interleaved 模式的 region 无法创建混合模式的namespaces,这个issue 解决可以参考 https://github.com/pmem/ndctl/issues/181。

关于ipmctl 工具的使用都需要在root 模式下执行

3.2 创建AppDirect mode的region

  1. 查看当前已有mode

    # ipmctl show -memoryresourcesMemoryType | DDR | PMemModule | Total
    ==========================================================
    Volatile | 384.000 GiB | 0.000 GiB | 384.000 GiB
    AppDirect | - | 1008.000 GiB | 1008.000 GiB
    Cache | 0.000 GiB | - | 0.000 GiB
    Inaccessible | 0.000 GiB | 3.377 GiB | 3.377 GiB
    Physical | 384.000 GiB | 1011.377 GiB | 1395.377 GiB
    

    上面这个是AppDirectmode

  2. 创建AppDirect mode,这个命令会将当前的所有容量默认创建出interleaved mode的 region

    # ipmctl create -goal PersistentMemoryType=AppDirect 
    The following configuration will be applied:SocketID | DimmID | MemorySize | AppDirect1Size | AppDirect2Size
    ==================================================================0x0000 | 0x0001 | 0.000 GiB | 126.000 GiB | 0.000 GiB0x0000 | 0x0011 | 0.000 GiB | 126.000 GiB | 0.000 GiB0x0000 | 0x0101 | 0.000 GiB | 126.000 GiB | 0.000 GiB0x0000 | 0x0111 | 0.000 GiB | 126.000 GiB | 0.000 GiB0x0001 | 0x1001 | 0.000 GiB | 126.000 GiB | 0.000 GiB0x0001 | 0x1011 | 0.000 GiB | 126.000 GiB | 0.000 GiB0x0001 | 0x1101 | 0.000 GiB | 126.000 GiB | 0.000 GiB0x0001 | 0x1111 | 0.000 GiB | 126.000 GiB | 0.000 GiB
    Do you want to continue? [y/n] y
    Created following region configuration goalSocketID | DimmID | MemorySize | AppDirect1Size | AppDirect2Size
    ==================================================================0x0000 | 0x0001 | 0.000 GiB | 126.000 GiB | 0.000 GiB0x0000 | 0x0011 | 0.000 GiB | 126.000 GiB | 0.000 GiB0x0000 | 0x0101 | 0.000 GiB | 126.000 GiB | 0.000 GiB0x0000 | 0x0111 | 0.000 GiB | 126.000 GiB | 0.000 GiB0x0001 | 0x1001 | 0.000 GiB | 126.000 GiB | 0.000 GiB0x0001 | 0x1011 | 0.000 GiB | 126.000 GiB | 0.000 GiB0x0001 | 0x1101 | 0.000 GiB | 126.000 GiB | 0.000 GiB0x0001 | 0x1111 | 0.000 GiB | 126.000 GiB | 0.000 GiB
    A reboot is required to process new memory allocation goals.
    # reboot -n
    

    如果 想创建non-interleaved 模式的region,则可以执行命令:
    ipmctl create -goal PersistentMemoryType=AppDirectNotInterleaved

3.3 创建 Memory Mode模式

其中 MemoryMode 是一个百分比,如果是100的话则表示当前所有的pmem module 容量都会作为memory mode。

# ipmctl create -goal MemoryMode=100
# reboot

重启之后,查看free -h 时能够看到内存的容量已经加上了所有的 pmem module 的容量了

3.4 创建 混合模式

创建内存模式的时候 有一个参数 MemoryMode 用来指定百分比,显而易见 我们可以在一个机器上让一部分的容量作为AppDirect 模式。
比如配置 50% 的容量为 memory mode 即可

# ipmctl create -goal MemoryMode=50

以上过程中如果想要清理所有的 config,可以通过 ipmctl delete –goal

3.5 查看创建的结果

  1. 查看 goal ipmctl show -goal
  2. 查看regions ipmctl show -region
  3. 查看内存资源情况 ipmctl show -memoryresources
  4. 查看 dimms 分布 ipmctl show -dimms

4 ndctl 创建不同类型的 namespaces

ndctl 的创建/删除/更新 namespace 需要root权限,查看namepace 信息则不需要root

4.1 安装

ndctl 的安装则不是很方便,如果系统库不全的话可能遇到的问题会比较多,我将我的安装完整过程贴下来:

  1. 前置库安装
     sudo yum install autoconf pkg-config libndctl-devel libdaxctl-devel pandoc -y
    
  2. 安装过程
    git clone https://github.com/pmem/ndctl.git
    cd ndctl
    git checkout v71 # 当前的最新版本./autogen.shActivated pre-commit hook.GIT_VERSION = 71sh: aclocal: command not foundautoreconf: aclocal failed with exit status: 127 # 执行失败
    ----------------------------------------------------# 解决
    sudo yum install automake libtool -y
    autoreconf -ivf# 执行成功
    $ ./autogen.sh
    ----------------------------------------------------------------
    Initialized build system. For a common configuration please run:
    ----------------------------------------------------------------
    ./configure CFLAGS='-g -O2' --prefix=/usr --sysconfdir=/etc --libdir=/usr/lib64# 执行./configure 
    ./configure CFLAGS='-g -O2' --prefix=/usr --sysconfdir=/etc --libdir=/usr/lib64
    ...
    checking for a sed that does not truncate output... (cached) /usr/bin/sed
    checking for asciidoctor... missing
    configure: error: asciidoctor needed to build documentation # 执行失败
    ----------------------------------------------------# 解决
    sudo yum install asciidoctor -y# 重新执行 ./configure
    ./configure CFLAGS='-g -O2' --prefix=/usr --sysconfdir=/etc --libdir=/usr/lib64
    ...
    checking for KMOD... no
    configure: error: Package requirements (libkmod) were not met:No package 'libkmod' foundConsider adjusting the PKG_CONFIG_PATH environment variable if you
    installed software in a non-standard prefix # 执行失败
    ----------------------------------------------------#解决
    sudo yum install kmod kmod-devel -y# 再次重新执行 ./configure
    ./configure CFLAGS='-g -O2' --prefix=/usr --sysconfdir=/etc --libdir=/usr/lib64
    ...
    configure: error: Package requirements (uuid) were not met:No package 'uuid' found #执行失败
    ----------------------------------------------------#解决
    sudo yum install libuuid-devel json-c-devel -y# 执行./configure 成功,生成 Makefile
    ./configure CFLAGS='-g -O2' --prefix=/usr --sysconfdir=/etc --libdir=/usr/lib64
    # 安装ndctl
    make && sudo make install
    

4.2 创建/删除 一个任意类型的namespace

  1. 查看已有的namespaces ndctl list --namespaces --regions
    能够展示所有创建好的可用的 namespace 以及其所属的 region信息完整打印出来。
  2. 创建一个namespace,如果不指定namespace 类型的话默认创建的是raw 类型
    ndctl create-namespace --force 
    
  3. 删除一个namespace 的话 可以通过 ndctl destroy-namespace namespace1.0 --force 或者 不指定具体的某一个namespace,直接--all 即可删除所有的namespaces,需要注意的是删除namespace 会清理掉当前namespace的所有数据

4.3 指定类型 创建 namespaces

  1. 创建一个fsdax 类型的namespace

    ndctl create-namespace --mode=fsdax --size=100G --region=region0 --force 
    

    指定在region0 上创建一个100G容量的 fsdax 模式namespace,创建成功则可以在lsblk 命令下看到这个块设备/dev/pmem0
    除了以上参数,还可以指定一个比较重要的配置--map=dev或者--map=mem,保存当前namespace 的元数据信息,大概是每4k 需要64B的存储。devmem 分别制定的是将这部分元数据存放在pmem设备上 或者 内存中。

  2. 上一条命令的基础上 在region0 创建一个devdax 模式的namespace

    ndctl create-namespace --mode=devdax --size=100G --region=region0 --force 
    

    创建好之后能ls -l /dev/dax1.0看到这个设备,它是一个字符设备。

    如果这一步失败,可以根据这个 issue 尝试解决:https://github.com/pmem/ndctl/issues/181

这样创建出来的namespace 对应的 region 以及 dimm 关系图如下:
在这里插入图片描述

4.4 变更已有namespace 类型

变更namespace1.0 的配置,从fsdax 模式变更为 devdax模式
ndctl create-namespace --mode=devdax --size=100G --reconfig=namespace1.0

注意:
reconfig 的流程会

  1. 先从已有的namespace中读取 元数据信息
  2. 然后删除已有的namespace,这一步会清理所有的数据
  3. 根据reconfig 的配置重新创建namespace

更多的创建信息,可以参考https://pmem.io/ndctl/ndctl-create-namespace.html

5 namespace 的应用

这里就很简单了,主要是针对fsdax 设备的使用
通过fsdax 模式创建出来的 一个块设备可以直接格式化成dax 支持的文件系统 并挂载:

sudo mkfs.xfs -f /dev/pmem0
sudo mount -o dax /dev/pmem0 /mnt/pmem0

此时即可使用文件接口进行读写。

6 fio测试 fsdax 和 devdax

建议测试的fio 版本直接使用最新的3.17,这样能够使用比较新的ioengine (libpmem/dev-dax)

  1. 测试fsdax

    以下绑定的numa 不一定准确,可以通过lscpu 查看numa的cpu,随便绑定一个,哪个性能好 则当前namespace 的region 就在哪个 numa上。

    [global]
    ioengine=libpmem #pmem引擎
    direct=1
    norandommap=1
    randrepeat=0
    runtime=60
    time_based
    size=1G
    directory=./fio
    group_reporting
    [read256B-rand]
    bs=256B
    rw=randread
    numjobs=32
    iodepth=4 
    cpus_allowed=0-15,16-31 #绑定numa
    

    当然,也有更准确的方法来找到当前pmem属于哪个numa.

    1. ndctl list --regions --namespaces 查看当前的 /dev/pmem0 属于哪一个region
    2. ipmctl show -region 查看当前的region 属于哪一个socket,0 则是numa node0, 1 则是numa node1等
  2. 测试devdax,不支持direct开启,直接访问的字符设备

    [global]
    ioengine=dev-dax
    direct=0
    norandommap=1
    randrepeat=0
    runtime=60
    time_based
    size=1G
    filename=/dev/dax1.0 #直接指定filename 为devdax模式的字符设备即可
    group_reporting
    [read256B-rand]
    bs=256B
    rw=randread
    numjobs=32
    iodepth=4 
    cpus_allowed=0-15,16-31 #绑定numa
    

到此已经完整得告诉了各位如何 从0到1 在一台服务器上创建一个混合模式的pmem 并做相关的应用 和测试,踩过的坑 希望能帮助各位节省一些时间,当然,更重要的是能够从宏观的角度中更进一步得了解pmem 设备 及其周边生态,毕竟是未来的高性能存储趋势。

7 参考

  1. Introduction to Persistent Memory Configuration and Analysis Tools
  2. Persistent Memory Provisioning Introduction
  3. support virtual persistent memory
  4. https://pmem.io/ndctl/
  5. https://nvdimm.wiki.kernel.org/
  6. NDCTL Introduction
  7. PMEM 主机安装环境详解

相关文章:

[PHP]php基础练习题学习随笔

1、解释一下PHP中常量、变量、可变变量并举例说明&#xff1b;超级全局变量有哪些&#xff1f; 常量是单个值的标识符&#xff08;名称&#xff09;&#xff0c;通过define()设置&#xff0c;在脚本中无法改变该值&#xff0c;常量自动全局。<?php #对大小写不敏感为true&a…

Java项目:进销存系统(java+Gui)

源码获取&#xff1a;博客首页 "资源" 里下载&#xff01; 功能介绍&#xff1a; 基本信息管理、库存管理、销售管理、订单管理、日志管理、供应商基本信息、员工基本信息、商品信息、入库管理、出库管理、剩余库存 商品信息控制层&#xff1a; /*** <p>* 前…

IDP申请直到软件上架流程 - iOS

第一&#xff1a;IDP的申请 1.先在iPhone DevCenter上注册成为iphone developer 2.加入iPhone开发程序项目iPhone Developer Program Apply Now 3.打算收费的都建议选择99刀那个&#xff0c;QTY是个数的意思。1就好。 4.选择地区china&#xff0c;(很早之前没有china&#xff0…

灭霸—个人冲刺(4)

灵魂三问&#xff1a;昨天做了什么&#xff1f;1.手机验证码 2h 2.整体框架搭建尝试 2h 目标任务量&#xff1a;100% 完成任务量&#xff1a;100% 今天要做什么&#xff1f;1.数据库建立及连接 16h 遇到困难没有&#xff1f;2.整体框架搭建时因为连接服务器分为三类&#xf…

关于 Rocksdb 的 EnvWrapper 作用的小讨论

临下班前一位做引擎的小伙伴提了个小问题&#xff0c; Rocksdb 实现了非常多的Env backend 这一些backend 可以让用户根据自己需求创建不同 公共接口backend&#xff0c;来实现自己的文件操作或者公共线程池操作。 Env* env new rocksdb::HdfsEnv(FLAGS_hdfs) 问题是&#xf…

corepython第九章:文件和输入输出

学习笔记: OS模块代码示例: 1 import os2 for tmpdir in (/tmp,rc:\users\administrator\desktop):3 #如果存在括号里面的目录&#xff0c;则break4 if os.path.isdir(tmpdir):5 break6 #如果不存在&#xff0c;则tmpdir为空值&#xff0c;即False7 else:8 pri…

Java项目:学生管理系统(无库版)(java+打印控制台)

源码获取&#xff1a;博客首页 "资源" 里下载&#xff01; 功能介绍&#xff1a; 学生成绩管理系统成绩表 用户管理操作&#xff1a; /*** 用户管理操作*/ Controller RequestMapping("/user") public class UserController {Autowiredprivate UserServi…

构建ASP.NET MVC4+EF5+EasyUI+Unity2.x注入的后台管理系统(12)-系统日志和异常的处理②...

原文:构建ASP.NET MVC4EF5EasyUIUnity2.x注入的后台管理系统&#xff08;12&#xff09;-系统日志和异常的处理② 上一讲我们做了日志与异常的结果显示列表&#xff0c;这一节我们讲要把他应用系统中来。 首先我们在App.Common类库中创建一个通用类ResultHelper&#xff0c;这个…

爬取猫眼怦然心动电影评论

作业要求来源&#xff1a;https://edu.cnblogs.com/campus/gzcc/GZCC-16SE1/homework/3159 可以用pandas读出之前保存的数据&#xff1a; newsdf pd.read_csv(rF:\duym\gzccnews.csv) 一.把爬取的内容保存到数据库sqlite3 import sqlite3with sqlite3.connect(gzccnewsdb.sqli…

TCMalloc(Thread-Caching malloc) 基本设计原理

文章目录背景如何使用架构概览1. TCMalloc Front-end1.1 小对象和大对象的内存分配过程1.2 内存释放过程1.3 Per-CPU mode1.4 Per-thread mode1.5 per-cpu 和 per-thread 运行时内存管理算法对比2. TCMalloc Middle-end2.1 Transfer Cache2.2 Central Free List2.3 Pagemap 和 …

Java项目:控制台商城系统(java+打印控制台)

源码获取&#xff1a;博客首页 "资源" 里下载&#xff01; 功能简介&#xff1a; 客户信息管理、商品信息管理、购物信息管理、退出系统 显示系统主菜单&#xff1a; public class SystemMenu {//显示系统主菜单public void showMainMenu(){System.out.println(&qu…

PAT (Basic Level) Practise (中文)-1025. 反转链表 (25)

PAT (Basic Level) Practise &#xff08;中文&#xff09;-1025. 反转链表 (25) http://www.patest.cn/contests/pat-b-practise/1025 给定一个常数K以及一个单链表L&#xff0c;请编写程序将L中每K个结点反转。例如&#xff1a;给定L为1→2→3→4→5→6&#xff0c;K为3&am…

初识Quartz(三)

为什么80%的码农都做不了架构师&#xff1f;>>> 简单作业&#xff1a; package quartz_project.example3;import java.util.Date;import org.quartz.Job; import org.quartz.JobExecutionContext; import org.quartz.JobExecutionException; import org.quartz.Job…

内存分配器设计的演进

文章目录栈内存空间是否够用系统调用申请内存最简单的内存分配器实现 -- bump allocator可扩容的 Bump alloactor通过free-list 管理的 allocator通过size-buckets 维护多个free-list 的 allocatorCache friendly allocator需要考虑更多问题的allocator性能易用性本文希望描述一…

Android OpenGL ES(十一)绘制一个20面体 .

前面介绍了OpenGL ES所有能够绘制的基本图形&#xff0c;点&#xff0c;线段和三角形。其它所有复杂的2D或3D图形都是由这些基本图形构成。 本例介绍如何使用三角形构造一个正20面体。一个正20面体&#xff0c;有12个顶点&#xff0c;20个面&#xff0c;30条边构成&#xff1a;…

Java项目:学生选课系统(java+javaweb+jdbc)

源码获取&#xff1a;博客首页 "资源" 里下载&#xff01; 功能介绍&#xff1a; 用户菜单、学生管理、教师管理、课程管理、成绩排名查询 学生管理控制层&#xff1a; Controller RequestMapping("/student") public class StudentController {private …

Xtrabackup对mysql全备以及增量备份实施

Xtrabackup对mysql全备以及增量备份实施1.完全备份与恢复本文使用的是centos5.8 64位系统&#xff0c;mysql 使用5.5.35.如果要使用一个最小权限的用户进行备份&#xff0c;可基于以下&#xff1a;mysql> createuser bkuserlocalhost identified by redhat;mysql> grant …

js浅拷贝和深拷贝

浅度拷贝&#xff1a;复制一层对象的属性&#xff0c;并不包括对象里面的为引用类型的数据&#xff0c;当改变拷贝的对象里面的引用类型时&#xff0c;源对象也会改变。 深度拷贝&#xff1a;重新开辟一个内存空间&#xff0c;需要递归拷贝对象里的引用&#xff0c;直到子属性都…

关于 fallocate 文件系统预分配 的一些细粒度测试

文章目录Rocksdb 中的预分配Fallocate in rocksdb 性能测试Fallocate 使用 以及 对应配置的行为API 使用不同 Mode 的行为分配磁盘空间释放磁盘空间折叠/裁剪 文件内容清零文件 扩容文件Rocksdb 中的预分配 预分配文件存储空间 在存储引擎中用的还是比较频繁的&#xff0c;尤…

mac 使用nvm安装node

1.curl https://raw.github.com/creationix/nvm/master/install.sh | sh2。vi ~/.bash_profile 添加&#xff1a;source /Users/dujie/.nvm/nvm.sh nvm install 0.10.24 nvm use 0.10.24 # 默認使用 0.10.24 版本&#xff0c;否則每次關掉 Terminal 就得重新 nvm use 一次 $…

Java项目:人事管理系统(java+javaweb+jdbc)

源码获取&#xff1a;博客首页 "资源" 里下载&#xff01; 功能介绍&#xff1a; 登录、新增、修改、离职 员工管理控制层&#xff1a; Controller RequestMapping("/employee") public class EmployeeController {Autowiredprivate IEmployeeService em…

转:async await 的前世今生 ; 异步 线程 多线程

写的非常好,改天搬过来

ubuntu14.04初体会

2014年4月17日ubuntu新的长期支持版14.04公布了&#xff0c;中国时间18日一早就能够下载到。18日晚。在我的X200上安装上了14.04&#xff0c;算是比較早一批体会到14.04正式版的人吧。对照12.04&#xff0c;14.04提升的执行速度非常明显&#xff0c;界面改善也是令人眼前一亮&a…

Linux 下获取本机所有网卡 以及 网卡对应ip 列表

简单record 一下 #include <arpa/inet.h> // struct sockaddr_in #include <errno.h> #include <net/if.h> // struct ifreq and struct if_nameindex #include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/i…

Java项目:植物大战僵尸(java+swing)

源码获取&#xff1a;博客首页 "资源" 里下载&#xff01; 功能简介&#xff1a; 植物大战僵尸、冒险模式、生存模式、解谜模式 小车服务类&#xff1a; public class CarThread extends Thread{private boolean flagtrue;private int x;private int y;private JL…

秋实大哥の恋爱物语

//裸kmp&#xff0c;劳资居然不会写&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff01; 题意&#xff1a;中文题面自己看 解&#xff1a;差分裸kmp 因为可以上下移动&#xff0c;所以只要变化趋势相符就行&#xff0c;于是我们先做一个差分&#xff0c…

《马哥出品高薪linux运维教程》wingkeung学习笔记-linux基础入门课程5

命令&#xff1a;内部命令&#xff1a;由shell程序自带的命令叫做内部命令&#xff1b;外部命令&#xff1a;在系统的某个路径下&#xff0c;有一个与命令同名的可执行程序叫做外部命令。查看内外部命令的命令&#xff1a;type 命令命令选项&#xff1a;用于调整命令执行行为的…

八、LaTex中的表格

转载于:https://www.cnblogs.com/invisible2/p/10813964.html

基于持久内存的 单机上亿(128B)QPS -- 持久化 k/v 存储引擎

文章目录性能数据设计背景设计架构Hash 索引结构 及 PMEM空间管理形态基本API 及 实现API初始化流程写流程读流程删除流程PMEM Allocator设计主要组件空间分配流程空间释放图数据库 on KVDK 性能性能数据 这个kv 存储引擎是持久化的存储引擎&#xff0c;存储介质是PMEM&#x…

SCALA当的trait

不是特别懂&#xff0c;但感觉和RUBY当中的MIX-IN功能有几分相似&#xff0c;这又扯到了多重继承及JAVA当中的接口虚拟类了。。 package com.hengheng.scalaclass UseTrait {} trait Logger {def log(msg : String) {println("log : " msg)} } trait ConsoleLogger …