From 5420cb73659608b11fb6032db375998bf45395d9 Mon Sep 17 00:00:00 2001 From: edisonlou Date: Thu, 18 Mar 2021 12:02:33 +0800 Subject: [PATCH] add code for etmem --- README.en.md | 36 -------- README.md | 231 +++++++++++++++++++++++++++++++++++++++++------ etmem-1.0.tar.gz | Bin 0 -> 33715 bytes etmem.spec | 48 ++++++++++ 4 files changed, 253 insertions(+), 62 deletions(-) delete mode 100644 README.en.md create mode 100644 etmem-1.0.tar.gz create mode 100644 etmem.spec diff --git a/README.en.md b/README.en.md deleted file mode 100644 index c167b74..0000000 --- a/README.en.md +++ /dev/null @@ -1,36 +0,0 @@ -# etmem - -#### Description -etmem, the memory vertical expansion technology, uses DRAM and high-performance storage new media to form multi-level memory storage. By grading the stored data, etmem migrates the classified cold storage data from memory to the high-performance storage medium, so as to achieve the purpose of memory capacity expansion and memory cost reduction. - -#### Software Architecture -Software architecture description - -#### Installation - -1. xxxx -2. xxxx -3. xxxx - -#### Instructions - -1. xxxx -2. xxxx -3. xxxx - -#### Contribution - -1. Fork the repository -2. Create Feat_xxx branch -3. Commit your code -4. Create Pull Request - - -#### Gitee Feature - -1. You can use Readme\_XXX.md to support different languages, such as Readme\_en.md, Readme\_zh.md -2. Gitee blog [blog.gitee.com](https://blog.gitee.com) -3. Explore open source project [https://gitee.com/explore](https://gitee.com/explore) -4. The most valuable open source project [GVP](https://gitee.com/gvp) -5. The manual of Gitee [https://gitee.com/help](https://gitee.com/help) -6. The most popular members [https://gitee.com/gitee-stars/](https://gitee.com/gitee-stars/) diff --git a/README.md b/README.md index 8d41150..54e28f9 100644 --- a/README.md +++ b/README.md @@ -1,37 +1,216 @@ # etmem -#### 介绍 -etmem, the memory vertical expansion technology, uses DRAM and high-performance storage new media to form multi-level memory storage. By grading the stored data, etmem migrates the classified cold storage data from memory to the high-performance storage medium, so as to achieve the purpose of memory capacity expansion and memory cost reduction. +## 介绍 -#### 软件架构 -软件架构说明 +随着CPU算力的发展,尤其是ARM核成本的降低,内存成本和内存容量成为约束业务成本和性能的核心痛点,因此如何节省内存成本,如何扩大内存容量成为存储迫切要解决的问题。 +etmem内存垂直扩展技术,通过DRAM+内存压缩/高性能存储新介质形成多级内存存储,对内存数据进行分级,将分级后的内存冷数据从内存介质迁移到高性能存储介质中,达到内存容量扩展的目的,从而实现内存成本下降。 -#### 安装教程 +## 安装教程 -1. xxxx -2. xxxx -3. xxxx +1. 下载etmem源码 -#### 使用说明 + $ git clone https://gitee.com/src-openeuler/etmem.git -1. xxxx -2. xxxx -3. xxxx +2. 编译安装 -#### 参与贡献 + $ cd etmem -1. Fork 本仓库 -2. 新建 Feat_xxx 分支 + $ mkdir build + + $ cd build + + $ cmake .. + + $ make + + $ make install + +## 使用说明 + +### 启动etmemd进程 + +#### 使用方法 + +通过运行etmemd二进制运行服务端进程,例如: + +$ etmemd -l 0 -s etmemd_socket + +#### 帮助信息 + +options: + +-l|--log-level Log level +-s|--socket Socket name to listen to +-h|--help Show this message + +#### 命令行参数说明 + +| 参数 | 参数含义 | 是否必须 | 是否有参数 | 参数范围 | 示例说明 | +| --------------- | ---------------------------------- | -------- | ---------- | --------------------- | ------------------------------------------------------------ | +| -l或--log-level | etmemd日志级别 | 否 | 是 | 0~3 | 0:debug级别 1:info级别 2:warning级别 3:error级别 只有大于等于配置的级别才会打印到/var/log/message文件中 | +| -s或--socket | etmemd监听的名称,用于与客户端交互 | 是 | 是 | 107个字符之内的字符串 | 指定服务端监听的名称 | +| -h或--help | 帮助信息 | 否 | 否 | NA | 执行时带有此参数会打印后退出 | + +### etmem配置文件 + +在运行etmem进程之前,需要管理员预先规划哪些进程需要做内存扩展,将进程信息配置到etmem配置文件中,并配置内存扫描的周期、扫描次数、内存冷热阈值等信息。 + +配置文件的示例文件在安装etmem软件包后,放置在/etc/etmem/example_conf.yaml,示例内容为: + +``` +options: + loop : 3 + interval : 1 + sleep: 2 + policies: + type : pid/name + value : 123456/mysql + max_threads: 3 + engine : slide + param: + T: 3 +``` + +配置文件各字段说明: + +| **置项** | **配置项含义** | **是否必须** | **是否有参数** | **参数范围** | **示例说明** | +| ----------- | ------------------------------------------------------------ | ------------ | -------------- | ------------------------- | ------------------------------------------------------------ | +| options | project公用配置段起始标识 | 是 | 否 | NA | 每个配置文件有且仅有一个此字段,并且文件以此字段开始 | +| loop | 内存扫描的循环次数 | 是 | 是 | 1~120 | loop:3 //扫描3次 | +| interval | 每次内存扫描的时间间隔 | 是 | 是 | 1~1200 | interval:5 //每次扫描之间间隔5s | +| sleep | 每个内存扫描+操作的大周期之间时间间隔 | 是 | 是 | 1~1200 | sleep:10 //每次大周期之间间隔10s | +| policies | project中各task任务配置段起始标识 | 是 | 否 | NA | 一个project中可以配置多个task,每个task以policies:开头 | +| type | 目标进程识别的方式 | 是 | 是 | pid/name | pid代表通过进程号识别,name代表通过进程名称识别 | +| value | 目标进程识别的具体字段 | 是 | 是 | 实际的进程号/进程名称 | 与type字段配合使用,指定目标进程的进程号或进程名称,由使用者保证配置的正确及唯一性 | +| max_threads | etmemd内部线程池最大线程数,每个线程处理一个进程/子进程的内存扫描+操作任务 | 否 | 是 | 1~2 * core数 + 1,默认为1 | 对外部无表象,控制etmemd服务端内部处理线程个数,当目标进程有多个子进程时,配置越大,并发执行的个数也多,但占用资源也越多 | +| engine | 扫描引擎类型 | 是 | 是 | slide | 声明使用slide引擎进行冷热内存识别 | +| param | 扫描引擎私有参数配置起始标识 | 是 | 否 | NA | 引擎私有参数配置段以此标识起始,每个task对应一种引擎,每个引擎对应一个param及其字段 | +| T | slide引擎的水线配置 | 是 | 否 | 1~3 * loop | 水线阈值,大于等于此值的内存会被识别为热内存,反之为冷内存 | + +### etmem工程创建/删除/查询 + +#### 场景描述 + +1)管理员创建etmem工程(一个工程可包含多个etmem任务) + +2)管理员查询已有的etmem工程 + +3)管理员删除已有的etmem工程(删除工程前,会自动先停止该工程中的所有任务) + +#### 使用方法 + +通过etmem二进制执行工程创建/删除/查询操作,前提是服务端已经成功运行,并且配置文件/etc/etmem/example_conf.yaml内容正确。 + +添加工程: + +etmem project add -n test -f /etc/etmem/example_conf.yaml -s etmemd_socket + +删除工程: + +etmem project del -n test -s etmemd_socket + +查询工程: + +etmem project show -s etmemd_socket + +打印帮助: + +etmem project help + +#### 帮助信息 + +Usage: + etmem project add [options] + etmem project del [options] + etmem project show + etmem project help + + Options: + -f|--file Add configuration file + -n|--name Add project name + -s|--sock Socket name to connect + + Notes: + \1. Project name and socket name must be given when execute add or del option. + \2. Configuration file must be given when execute add option. + \3. Socket name must be given when execute show option. + +#### 命令行参数说明 + +add命令: + +| 参数 | 参数含义 | 是否必须 | 是否有参数 | 示例说明 | +| ------------ | ------------------------------------------------------------ | -------- | ---------- | -------------------------------------------------------- | +| -n或--name | 指定project名称 | 是 | 是 | project名称,与配置文件一一对应 | +| -f或--file | 指定project的配置文件 | 是 | 是 | 需要指定路径名称 | +| -s或--socket | 与etmemd服务端通信的socket名称,需要与etmemd启动时指定的保持一致 | 是 | 是 | 必须配置,在有多个etmemd时,由管理员选择与哪个etmemd通信 | + +del命令: + +| 参数 | 参数含义 | 是否必须 | 是否有参数 | 示例说明 | +| ------------ | ------------------------------------------------------------ | -------- | ---------- | -------------------------------------------------------- | +| -n或--name | 指定project名称 | 是 | 是 | project名称,与配置文件一一对应 | +| -s或--socket | 与etmemd服务端通信的socket名称,需要与etmemd启动时指定的保持一致 | 是 | 是 | 必须配置,在有多个etmemd时,由管理员选择与哪个etmemd通信 | + +show命令: + +| 参数 | 参数含义 | 是否必须 | 是否有参数 | 示例说明 | +| ------------ | ------------------------------------------------------------ | -------- | ---------- | -------------------------------------------------------- | +| -s或--socket | 与etmemd服务端通信的socket名称,需要与etmemd启动时指定的保持一致 | 是 | 是 | 必须配置,在有多个etmemd时,由管理员选择与哪个etmemd通信 | + +### etmem任务启动/停止 + +#### 场景描述 + +在已经通过etmem project add添加工程之后,在还未调用etmem project del删除工程之前,可以对etmem的工程进行启动和停止。 + +1)管理员启动已添加的工程 + +2)管理员停止已启动的工程 + +在管理员调用project del删除工程时,如果工程已经启动,则会自动停止。 + +#### 使用方法 + +通过etmem二进制执行任务启动/停止操作,前提是服务端已经成功运行,配置文件/etc/etmem/example_conf.yaml内容正确,且etmem工程已经创建。 + +启动工程 + +etmem migrate start -n test -s etmemd_socket + +停止工程 + +etmem migrate stop -n test -s etmemd_socket + +打印帮助 + +etmem migrate help + +#### 帮助信息 + +Usage: + etmem migrate start [options] + etmem migrate stop [options] + etmem migrate help + + Options: + -n|--name Add project name + -s|--sock Socket name to connect + + Notes: + Project name and socket name must be given when execute start or stop option. + +#### 命令行参数说明 + +| 参数 | 参数含义 | 是否必须 | 是否有参数 | 示例说明 | +| ------------ | ------------------------------------------------------------ | -------- | ---------- | -------------------------------------------------------- | +| -n或--name | 指定project名称 | 是 | 是 | project名称,与配置文件一一对应 | +| -s或--socket | 与etmemd服务端通信的socket名称,需要与etmemd启动时指定的保持一致 | 是 | 是 | 必须配置,在有多个etmemd时,由管理员选择与哪个etmemd通信 | + +## 参与贡献 + +1. Fork本仓库 +2. 新建个人分支 3. 提交代码 -4. 新建 Pull Request - - -#### 特技 - -1. 使用 Readme\_XXX.md 来支持不同的语言,例如 Readme\_en.md, Readme\_zh.md -2. Gitee 官方博客 [blog.gitee.com](https://blog.gitee.com) -3. 你可以 [https://gitee.com/explore](https://gitee.com/explore) 这个地址来了解 Gitee 上的优秀开源项目 -4. [GVP](https://gitee.com/gvp) 全称是 Gitee 最有价值开源项目,是综合评定出的优秀开源项目 -5. Gitee 官方提供的使用手册 [https://gitee.com/help](https://gitee.com/help) -6. Gitee 封面人物是一档用来展示 Gitee 会员风采的栏目 [https://gitee.com/gitee-stars/](https://gitee.com/gitee-stars/) +4. 新建Pull Request \ No newline at end of file diff --git a/etmem-1.0.tar.gz b/etmem-1.0.tar.gz new file mode 100644 index 0000000000000000000000000000000000000000..50096c482043284079cf7236949dfb32e26dafed GIT binary patch literal 33715 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%0DdW*Z&X; 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 +- Package init