书籍详情
持久内存编程
作者:[美] 史蒂夫·斯卡格尔(Steve Scargall) 著,吴国安 魏剑 杨锦文 等 译
出版社:机械工业出版社
出版时间:2021-04-01
ISBN:9787111676744
定价:¥119.00
购买这本书可以去
内容简介
本书介绍了持久内存编程技术应用前景,涵盖持久内存的操作系统和硬件要求,以及如何使用模拟和真实的持久内存硬件创建开发环境。本书对持久内存的基本概念进行了解释,介绍了面向 C、C++、JavaScript 和其他语言的持久内存编程 API,探讨了采用持久内存的 RDMA,回顾了安全特性,并展示了许多示例。读者可以在自己的系统上运行本书提供的源代码和示例。
作者简介
【作者简介】 Steve Scargall是英特尔公司的一名持久内存软件/云架构师。作为一名技术宣传官,Steve Scargall负责提供技术的启动与开发支持工作,以便将持久内存技术集成到软件栈、应用程序和硬件架构中,包括在专有和开源开发工作方面与独立软件开发商(ISV)进行合作,以及与原始设备制造商(OEM)和云服务提供商(CSP)等合作。 Steve曾在英国雷丁大学潜心学习神经网络、人工智能和机器人等知识,获得了计算机科学和控制论专业学士学位。他曾负责为Solaris Kernel、ZFS和UFS文件系统提供x86架构与SPARC性能分析支持,拥有超过19年的丰富经验。在Sun Microsystems和Oracle工作期间,他负责企业和云环境中的DTrace调试工作。 【译者简介】 吴国安(Dennis)2005年于上海交通大学硕士研究生毕业。目前是英特尔持久内存工程部经理,在IA架构、性能优化、软件协同硬件开发方面有多年工作经验。目前主要支持客户应用英特尔数据中心级持久化内存进行软件开发和应用适配,提供IA架构上的客户方案技术咨询和支持。在2012年加入英特尔之前,任职意法半导体,负责数字电视软件开发和集成的工作。魏剑(Terry Wei)是英特尔傲腾技术方案专家,在英特尔供职16年,曾担任硬件开发、客户技术支持等多种职位,目前主要致力于傲腾存储技术在中国用户环境的技术适配和应用推广方面的工作。杨锦文(Jinwen Yang)负责英特尔中国区云计算和互联网行业的战略规划和数据中心产品线的市场导入,并整合内部和外部技术资源,不断优化数据中心的全栈式解决方案,专注于服务客户的多样化需求。吴少慧(Shaohui Wu)目前是英特尔持久内存工程师,拥有清华大学工程物理系的工程学士学位以及北京有色金属研究总院金属材料及热处理专业的工程硕士学位。2018年入职英特尔之前,从事半导体芯片的产品开发与制造方面的工作,目前主要致力于傲腾持久内存生态环境的建立,并推广持久内存在中国区的应用。许春晔(Chunye Xu)是英特尔公司的持久内存应用工程师,致力于客户持久内存技术支持和工作负载调试工作,曾在英特尔通信和设备部门负责系统调试和自动化测试工作。他毕业于河北大学,拥有计算机应用硕士学位。林翔(Xiang Lin)是英特尔公司的平台应用工程师,目前主要致力于持久内存的应用和研究工作,包括工作负载的应用和性能优化,同时还负责客户支持方面的工作。此外,他对图形图像处理领域有着浓厚的兴趣。王龙(Long Wang)是英特尔公司的软件工程师,当前主要致力于持久内存相关的数据库开发与性能优化,同时还参与PMDK项目,例如远程持久内存访问的集成开发工作。李晓冉(Xiaoran Li)2018年毕业于日本北海道大学信息与科学学院,目前就职于英特尔数据中心部门,从事傲腾持久内存研发工作,对系统存储、云计算、并行计算有浓厚兴趣。斯佩峰(Peifeng Si)是英特尔数据中心部门资深软件工程师。长期从事x86服务器的固件开发和软件性能调优,目前专注于持久内存对数据库及存储类应用的优化。陶少玉(Shaoyu Tao)在英特尔任职软件工程师超过5年,在加入英特尔的前几年,他主要从事Linux内核、系统调试相关工作,目前专注于基于持久内存的数据库优化相关工作。高明(Ming Gao)是英特尔公司中国区行业解决方案部互联网行业技术总监,他主要负责英特尔与中国互联网公司的技术战略合作,助力中国互联网公司利用英特尔的产品和技术构建云计算解决方案,对包括人工智能在内的各类工作负载进行性能优化。高明获得了北京邮电大学计算机科学与技术专业硕士学位。崔峰 2015年5月起就职于京天石易通信息技术有限公司,至今从业超过15年,2004年毕业于英国诺桑比亚大学,获商业管理学士学位。
目录
第1章 持久内存编程简介 1
1.1 高级示例程序 2
1.1.1 有何区别 4
1.1.2 性能差异 5
1.1.3 程序复杂性 5
1.1.4 libpmemkv如何运行 5
1.2 后文提要 6
1.3 总结 7
第2章 持久内存架构 8
2.1 持久内存的特性 8
2.2 持久内存的平台支持 9
2.3 缓存层级 10
2.4 电源故障保护域 11
2.5 刷新、排序和屏障操作的需求 13
2.6 数据可见性 16
2.7 用于持久内存的英特尔机器指令 16
2.8 检测平台功能 17
2.9 应用程序启动与恢复 18
2.10 后文提要 20
2.11 总结 20
第3章 持久内存的操作系统支持 21
3.1 内存和存储的操作系统支持 21
3.2 持久内存用作块存储 22
3.3 持久内存感知型文件系统 23
3.4 内存映射文件 24
3.5 持久内存直接访问 30
3.6 总结 37
第4章 持久内存编程的基本概念 38
4.1 有何区别 38
4.2 原子更新 39
4.3 事务 39
4.3.1 原子性 39
4.3.2 一致性 40
4.3.3 隔离性 40
4.3.4 持久性 40
4.4 刷新不具有事务性 41
4.5 启动时职责 41
4.6 针对硬件配置进行调优 41
4.7 总结 42
第5章 持久内存开发套件简介 43
5.1 背景 43
5.2 选择正确的语义 44
5.3 易失性库 44
5.3.1 libmemkind 44
5.3.2 libvmemcache 45
5.3.3 libvmem 46
5.4 持久性库 46
5.4.1 libpmem 46
5.4.2 libpmemobj 46
5.4.3 libpmemobj-cpp 47
5.4.4 libpmemkv 47
5.4.5 libpmemlog 47
5.4.6 libpmemblk 48
5.5 工具和命令程序 48
5.5.1 pmempool 48
5.5.2 pmemcheck 48
5.5.3 pmreorder 49
5.6 总结 49
第6章 libpmem:底层持久内存支持 50
6.1 使用库 51
6.2 映射文件 51
6.3 复制到持久内存 52
6.4 分解刷新步骤 53
6.5 总结 54
第7章 libpmemobj:原生事务性对象存储 55
7.1 什么是libpmemobj 55
7.2 为什么不使用malloc() 55
7.3 组合操作 56
7.4 内存池 56
7.4.1 创建内存池 56
7.4.2 池对象指针和根对象 59
7.4.3 打开内存池并从内存池中读取数据 60
7.5 内存池集 61
7.5.1 串联池集 61
7.5.2 副本池集 62
7.6 管理内存池和池集 62
7.7 类型化对象标识符 63
7.8 分配内存 63
7.9 持久保存数据 63
7.9.1 原子操作 64
7.9.2 保留/发布API 66
7.9.3 事务API 68
7.9.4 可选标记 71
7.9.5 持久保存数据总结 71
7.10 libpmemobj的API可提供保障 71
7.11 管理库操作 72
7.12 调试与错误处理 72
7.13 总结 74
第8章 libpmemobj-cpp:自适应语言C++和持久内存 75
8.1 简介 75
8.2 元编程 75
8.2.1 持久指针 76
8.2.2 事务 76
8.2.3 创建快照 77
8.2.4 分配 79
8.3 C++标准限制 80
8.3.1 对象的生命周期 80
8.3.2 平凡类型 81
8.3.3 对象布局 82
8.3.4 指针 83
8.3.5 限制总结 85
8.4 简化持久性 85
8.5 生态系统 91
8.5.1 持久容器 91
8.5.2 持久容器示例 91
8.6 总结 94
第9章 pmemkv:持久内存键值存储 95
9.1 pmemkv架构 97
9.2 电话簿示例 99
9.3 让持久内存更靠近云 102
9.4 总结 103
第10章 持久内存编程的易失性用途 104
10.1 简介 104
10.2 背景 105
10.2.1 内存分配 105
10.2.2 工作原理 105
10.2.3 支持的内存“类型” 105
10.3 memkind API 107
10.3.1 类型管理API 107
10.3.2 堆管理API 111
10.3.3 类型配置管理 112
10.3.4 更多memkind代码示例 113
10.4 面向PMEM类型的C++分配器 113
10.4.1 pmem::allocator方法 114
10.4.2 嵌套容器 114
10.5 C++示例 114
10.5.1 使用pmem::allocator 115
10.5.2 创建字符串向量 115
10.6 使用持久内存扩展易失性内存 116
10.7 libvmemcache:面向大容量持久内存的高效易失性键值缓存 120
10.7.1 libvmemcache概述 120
10.7.2 libvmemcache设计 122
10.7.3 使用libvmemcache 124
10.8 总结 126
第11章 设计适用于持久内存的数据结构 127
11.1 连续数据结构和碎片化 127
11.1.1 内部和外部碎片化 127
11.1.2 原子性和一致性 128
11.1.3 选择性持久化 131
11.1.4 示例数据结构 131
11.2 总结 140
第12章 调试持久内存应用程序 141
12.1 用于Valgrind的pmemcheck 142
12.1.1 栈溢出示例 142
12.1.2 内存泄漏示例 143
12.2 Intel Inspector?—?Persistence Inspector 144
12.2.1 栈溢出示例 144
12.2.2 内存泄漏示例 145
12.3 常见的持久内存编程问题 146
12.3.1 非持久存储 146
12.3.2 数据存储未添加到事务 157
12.3.3 将一个内存对象添加至两个不同的事务 160
12.3.4 内存覆写 165
12.3.5 非必要刷新 166
12.3.6 乱序写入 170
12.4 总结 179
第13章 实际应用程序中实现持久性 180
13.1 数据库示例 180
13.2 不同的持久内存实现方式 181
13.3 开发持久内存感知型MariaDB*存储引擎 181
13.3.1 了解存储层 182
13.3.2 创建存储引擎类 183
13.4 总结 191
第14章 并发和持久内存 192
14.1 事务与多线程 192
14.2 持久内存上的互斥体 196
14.3 原子操作与持久内存 198
14.4 持久内存的并发数据结构 198
14.4.1 并发有序映射 199
14.4.2 并发散列映射 202
14.5 总结 202
第15章 分析与性能 204
15.1 简介 204
15.2 性能分析概念 204
15.2.1 计算受限与内存受限 204
15.2.2 内存延时与内存容量 205
15.2.3 读取与写入性能 205
15.2.4 内存访问模式 205
15.2.5 I/O存储受限的工作负载 205
15.3 确定工作负载是否适合持久内存 206
15.3.1 易失性用例 206
15.3.2 需要持久性的用例 208
15.4 使用持久内存的工作负载性能分析 209
15.4.1 确定工作负载特性 210
15.4.2 内存带宽与延时 210
15.4.3 持久内存读写比率 211
15.4.4 工作集大小与内存占用空间大小 211
15.4.5 非一致内存架构行为 211
15.4.6 优化面向持久内存的软件 212
15.5 总结 215
第16章 PMDK内部组件:重要算法和数据结构 216
16.1 持久内存池:高层架构概览 216
16.2 内存映射的不确定性:持久内存对象标识符 218
16.3 持久化线程本地存储:使用通道 220
16.4 确保电源故障原子性:重做日志和撤销日志 220
16.4.1 事务重做日志 221
16.4.2 事务撤销日志 221
16.4.3 libpmemobj统一日志 222
16.5 持久分配:事务持久分配器的接口 223
16.6 持久内存堆管理:持久内存分配器设计 223
16.7 ACID事务:高效的底层持久事务 226
16.8 延迟重新初始化变量:将易失性状态存储在持久内存上 227
16.9 总结 228
第17章 可靠性、可用性与可维护性 229
17.1 处理不可纠正错误 229
17.1.1 已使用的不可纠正错误处理 230
17.1.2 未使用的不可纠正错误处理 231
17.1.3 清除不可纠正错误 234
17.2 设备状态 234
17.2.1 ACPI定义的设备状态函数(_NCH,_NBS) 236
17.2.2 特定供应商的设备状态(_DSM) 236
17.2.3 ACPI NFIT状态事件通知 236
17.3 不安全/异常关机 237
17.4 总结 238
第18章 远程持久内存 239
18.1 RDMA网络协议 240
18.2 初始远程持久内存架构的目标 242
18.3 确保远程持久性 242
18.3.1 通用远程复制方法 243
18.3.2 设备远程复制方法 244
18.4 一般软件架构 246
18.5 librpmem架构及其在复制中的使用 246
18.5.1 使用内存池集配置远程复制 249
18.5.2 性能注意事项 249
18.5.3 远程复制错误处理 250
18.5.4 向复制世界“问好” 251
18.6 总结 254
第19章 高级主题 256
19.1 非一致性内存访问 256
19.1.1 NUMACTL Linux程序 257
19.1.2 NDCTL Linux程序 258
19.1.3 英特尔内存延迟检查器程序 259
19.1.4 NUMASTAT程序 260
19.1.5 英特尔VTune Profiler —Platform Profiler 261
19.1.6 IPMCTL程序 261
19.1.7 BIOS调优选项 261
19.1.8 自动NUMA平衡 261
19.2 使用具有持久内存的卷管理器 263
19.3 mmap()的MAP_SYNC标记 264
19.4 总结 265
附录A 如何在Linux上安装NDCTL和DAXCTL 266
附录B 如何安装持久内存开发套件 271
附录C 如何在Linux和Windows上安装IPMCTL 277
附录D 面向持久内存的Java 282
附录E 远程持久内存复制的未来 289
术语表 292
1.1 高级示例程序 2
1.1.1 有何区别 4
1.1.2 性能差异 5
1.1.3 程序复杂性 5
1.1.4 libpmemkv如何运行 5
1.2 后文提要 6
1.3 总结 7
第2章 持久内存架构 8
2.1 持久内存的特性 8
2.2 持久内存的平台支持 9
2.3 缓存层级 10
2.4 电源故障保护域 11
2.5 刷新、排序和屏障操作的需求 13
2.6 数据可见性 16
2.7 用于持久内存的英特尔机器指令 16
2.8 检测平台功能 17
2.9 应用程序启动与恢复 18
2.10 后文提要 20
2.11 总结 20
第3章 持久内存的操作系统支持 21
3.1 内存和存储的操作系统支持 21
3.2 持久内存用作块存储 22
3.3 持久内存感知型文件系统 23
3.4 内存映射文件 24
3.5 持久内存直接访问 30
3.6 总结 37
第4章 持久内存编程的基本概念 38
4.1 有何区别 38
4.2 原子更新 39
4.3 事务 39
4.3.1 原子性 39
4.3.2 一致性 40
4.3.3 隔离性 40
4.3.4 持久性 40
4.4 刷新不具有事务性 41
4.5 启动时职责 41
4.6 针对硬件配置进行调优 41
4.7 总结 42
第5章 持久内存开发套件简介 43
5.1 背景 43
5.2 选择正确的语义 44
5.3 易失性库 44
5.3.1 libmemkind 44
5.3.2 libvmemcache 45
5.3.3 libvmem 46
5.4 持久性库 46
5.4.1 libpmem 46
5.4.2 libpmemobj 46
5.4.3 libpmemobj-cpp 47
5.4.4 libpmemkv 47
5.4.5 libpmemlog 47
5.4.6 libpmemblk 48
5.5 工具和命令程序 48
5.5.1 pmempool 48
5.5.2 pmemcheck 48
5.5.3 pmreorder 49
5.6 总结 49
第6章 libpmem:底层持久内存支持 50
6.1 使用库 51
6.2 映射文件 51
6.3 复制到持久内存 52
6.4 分解刷新步骤 53
6.5 总结 54
第7章 libpmemobj:原生事务性对象存储 55
7.1 什么是libpmemobj 55
7.2 为什么不使用malloc() 55
7.3 组合操作 56
7.4 内存池 56
7.4.1 创建内存池 56
7.4.2 池对象指针和根对象 59
7.4.3 打开内存池并从内存池中读取数据 60
7.5 内存池集 61
7.5.1 串联池集 61
7.5.2 副本池集 62
7.6 管理内存池和池集 62
7.7 类型化对象标识符 63
7.8 分配内存 63
7.9 持久保存数据 63
7.9.1 原子操作 64
7.9.2 保留/发布API 66
7.9.3 事务API 68
7.9.4 可选标记 71
7.9.5 持久保存数据总结 71
7.10 libpmemobj的API可提供保障 71
7.11 管理库操作 72
7.12 调试与错误处理 72
7.13 总结 74
第8章 libpmemobj-cpp:自适应语言C++和持久内存 75
8.1 简介 75
8.2 元编程 75
8.2.1 持久指针 76
8.2.2 事务 76
8.2.3 创建快照 77
8.2.4 分配 79
8.3 C++标准限制 80
8.3.1 对象的生命周期 80
8.3.2 平凡类型 81
8.3.3 对象布局 82
8.3.4 指针 83
8.3.5 限制总结 85
8.4 简化持久性 85
8.5 生态系统 91
8.5.1 持久容器 91
8.5.2 持久容器示例 91
8.6 总结 94
第9章 pmemkv:持久内存键值存储 95
9.1 pmemkv架构 97
9.2 电话簿示例 99
9.3 让持久内存更靠近云 102
9.4 总结 103
第10章 持久内存编程的易失性用途 104
10.1 简介 104
10.2 背景 105
10.2.1 内存分配 105
10.2.2 工作原理 105
10.2.3 支持的内存“类型” 105
10.3 memkind API 107
10.3.1 类型管理API 107
10.3.2 堆管理API 111
10.3.3 类型配置管理 112
10.3.4 更多memkind代码示例 113
10.4 面向PMEM类型的C++分配器 113
10.4.1 pmem::allocator方法 114
10.4.2 嵌套容器 114
10.5 C++示例 114
10.5.1 使用pmem::allocator 115
10.5.2 创建字符串向量 115
10.6 使用持久内存扩展易失性内存 116
10.7 libvmemcache:面向大容量持久内存的高效易失性键值缓存 120
10.7.1 libvmemcache概述 120
10.7.2 libvmemcache设计 122
10.7.3 使用libvmemcache 124
10.8 总结 126
第11章 设计适用于持久内存的数据结构 127
11.1 连续数据结构和碎片化 127
11.1.1 内部和外部碎片化 127
11.1.2 原子性和一致性 128
11.1.3 选择性持久化 131
11.1.4 示例数据结构 131
11.2 总结 140
第12章 调试持久内存应用程序 141
12.1 用于Valgrind的pmemcheck 142
12.1.1 栈溢出示例 142
12.1.2 内存泄漏示例 143
12.2 Intel Inspector?—?Persistence Inspector 144
12.2.1 栈溢出示例 144
12.2.2 内存泄漏示例 145
12.3 常见的持久内存编程问题 146
12.3.1 非持久存储 146
12.3.2 数据存储未添加到事务 157
12.3.3 将一个内存对象添加至两个不同的事务 160
12.3.4 内存覆写 165
12.3.5 非必要刷新 166
12.3.6 乱序写入 170
12.4 总结 179
第13章 实际应用程序中实现持久性 180
13.1 数据库示例 180
13.2 不同的持久内存实现方式 181
13.3 开发持久内存感知型MariaDB*存储引擎 181
13.3.1 了解存储层 182
13.3.2 创建存储引擎类 183
13.4 总结 191
第14章 并发和持久内存 192
14.1 事务与多线程 192
14.2 持久内存上的互斥体 196
14.3 原子操作与持久内存 198
14.4 持久内存的并发数据结构 198
14.4.1 并发有序映射 199
14.4.2 并发散列映射 202
14.5 总结 202
第15章 分析与性能 204
15.1 简介 204
15.2 性能分析概念 204
15.2.1 计算受限与内存受限 204
15.2.2 内存延时与内存容量 205
15.2.3 读取与写入性能 205
15.2.4 内存访问模式 205
15.2.5 I/O存储受限的工作负载 205
15.3 确定工作负载是否适合持久内存 206
15.3.1 易失性用例 206
15.3.2 需要持久性的用例 208
15.4 使用持久内存的工作负载性能分析 209
15.4.1 确定工作负载特性 210
15.4.2 内存带宽与延时 210
15.4.3 持久内存读写比率 211
15.4.4 工作集大小与内存占用空间大小 211
15.4.5 非一致内存架构行为 211
15.4.6 优化面向持久内存的软件 212
15.5 总结 215
第16章 PMDK内部组件:重要算法和数据结构 216
16.1 持久内存池:高层架构概览 216
16.2 内存映射的不确定性:持久内存对象标识符 218
16.3 持久化线程本地存储:使用通道 220
16.4 确保电源故障原子性:重做日志和撤销日志 220
16.4.1 事务重做日志 221
16.4.2 事务撤销日志 221
16.4.3 libpmemobj统一日志 222
16.5 持久分配:事务持久分配器的接口 223
16.6 持久内存堆管理:持久内存分配器设计 223
16.7 ACID事务:高效的底层持久事务 226
16.8 延迟重新初始化变量:将易失性状态存储在持久内存上 227
16.9 总结 228
第17章 可靠性、可用性与可维护性 229
17.1 处理不可纠正错误 229
17.1.1 已使用的不可纠正错误处理 230
17.1.2 未使用的不可纠正错误处理 231
17.1.3 清除不可纠正错误 234
17.2 设备状态 234
17.2.1 ACPI定义的设备状态函数(_NCH,_NBS) 236
17.2.2 特定供应商的设备状态(_DSM) 236
17.2.3 ACPI NFIT状态事件通知 236
17.3 不安全/异常关机 237
17.4 总结 238
第18章 远程持久内存 239
18.1 RDMA网络协议 240
18.2 初始远程持久内存架构的目标 242
18.3 确保远程持久性 242
18.3.1 通用远程复制方法 243
18.3.2 设备远程复制方法 244
18.4 一般软件架构 246
18.5 librpmem架构及其在复制中的使用 246
18.5.1 使用内存池集配置远程复制 249
18.5.2 性能注意事项 249
18.5.3 远程复制错误处理 250
18.5.4 向复制世界“问好” 251
18.6 总结 254
第19章 高级主题 256
19.1 非一致性内存访问 256
19.1.1 NUMACTL Linux程序 257
19.1.2 NDCTL Linux程序 258
19.1.3 英特尔内存延迟检查器程序 259
19.1.4 NUMASTAT程序 260
19.1.5 英特尔VTune Profiler —Platform Profiler 261
19.1.6 IPMCTL程序 261
19.1.7 BIOS调优选项 261
19.1.8 自动NUMA平衡 261
19.2 使用具有持久内存的卷管理器 263
19.3 mmap()的MAP_SYNC标记 264
19.4 总结 265
附录A 如何在Linux上安装NDCTL和DAXCTL 266
附录B 如何安装持久内存开发套件 271
附录C 如何在Linux和Windows上安装IPMCTL 277
附录D 面向持久内存的Java 282
附录E 远程持久内存复制的未来 289
术语表 292
猜您喜欢