????????关注后回复 “进群” ,拉你进程序员交流群????????

作者丨码农的荒岛求生

来源丨码农的荒岛求生

大家好,我是小风哥。

在之前的文章《阿里终面:为什么不能把SSD当内存用?》中讨论了为什么SSD不能当内存用这一话题,然后就有很多同学跑过来咨询文章中提到的新硬件。

在这篇文章中博主提到了Intel有一款新设备,即能当内存用也能像磁盘一样持久化内存数据,很多同学咨询这种新硬件的编程问题,那么在这篇文章中小风哥就给大家聊聊这话题。

持久内存

在这里简单说下,这种新硬件就是Intel推出的傲腾持久内存,Intel Optane Persistent Memory ,这种硬件可以当做内存来用,和普通内存一样,但同时也具有非易失特性,像磁盘或者SSD一样断电后内存中的数据不会丢失,就是这么的神奇。

对于这类持久化内存来讲就真的没有重启一说了,因为数据会一直保存在内存里,加电后直接用即可,你的程序就再也没有启动或者初始化一说了,这是一种全新的设备,对程序员来说有一定的挑战。

那么针对这类硬件该如何编程呢?

面向存储编程

实际上数据结构或者说数据存放在两个地方:内存以及存储设备,这里的存储设备就是程序员熟悉的磁盘或者SSD。

对于需要将数据存放在存储设备的程序员来说,通常必须小心的维护数据的一致性,为什么呢?

对于高可靠程序来说你必须能随时应对断电或者程序崩溃,如果数据没有及时的从内存刷入磁盘,那么此时你的数据将会丢失;而如果在写入磁盘的过程中发生了断电或者程序崩溃crash,那么此时写入磁盘就是不完整的数据。

对于面向存储设备编程的程序员来说解决上述问题有一个常用的方法,那就是write-ahead logging。

你不是会随时断电或者随时程序崩溃吗,我在真正写入磁盘之前先写一段log,这段log的内容可能是这样的:“我要往磁盘中写入一句话,这句话是“小风哥太帅了!””。

那么假设在将真正的数据“小风哥太水了!”这个字符串写入磁盘的过程中机房断电或者程序崩溃,放心,在这种情况下是丢失不了数据的,此后程序在重启时通过再次读取该log:“我要往磁盘中写入一句话“小风哥太帅了!”,该程序就能获得足够的信息来再次往磁盘中写数据,这就是write-ahead logging的妙用。

到这里我先应该能大体明白这类程序员所面临的挑战了。

面向内存编程

而对于面向内存编程,也就是通常不需要关心数据持久存储问题的程序员来说也没那么容易,虽然你不需要关心数据持久存储所面临的一致性问题,但你需要在程序运行过程中解决多线程访问的一致性问题。

当多个线程访问同一段内存时,程序员通常需要加锁,这样当一个程序修改这段内存时可以确保其它线程不会看到中间状态——也就是修改到一半时的内存数据。

当断电或者程序崩溃后内存中的内容就消失了,因此你不需要去关心持久存储所面临的一致性问题。

内存数据断电后消失、程序崩溃后内存内容消失以及磁盘数据可以持久存储这些特性对于当前的程序员来说已经像空气一样习以为常了。

面向持久内存编程

现在告诉你,有一种新硬件,这种硬件能让你直接当内存来用,也就是可以直接字节寻址但与此同时断电后内容又不消失,你觉得会怎样?

我想会有很多同学大呼神奇,该技术可以让你获得大量廉价内存,同时内存中的数据在断电以及程序崩溃时内容不丢失。

但神奇的不止是这种硬件,针对该硬件进行编程同样需要编程思维上的转变。

从特性上看,该硬件即是内存又是磁盘,因此上面关于持久数据一致性以及多线程一致性的考虑都适用于该硬件,也就是说针对该硬件进行编程时你即需要考虑多线程访问一致性,也需要考虑持久数据一致性。

于此同时,最让C/C++的程序员头疼的问题之一,即内存泄漏在持久内存的场景下就更有挑战了,在普通内存下内存泄漏后大不了重启,而在持久内存场景下,如果出现了内存泄漏,那就是持久的内存泄漏,重启不再起作用

这些程序员来说一个极大的挑战。

For example

我们来看一个简单的示例:

假设这段代码出自银行的账户系统,定义了一个简单的结构体:结构体包含两项:用户姓名和账户余额:

struct account {string name;int money;
};

当有新用户存钱时,那么需要创建一个实例然后更新姓名和账户余额:

struct account *xfg = new account();
xfg->name = "xiaofengge";
xfg->money = 100000000; // 单位人民币

是的,你没有看错,小风哥在这段代码里已经财务自由了

这段代码在程序员看来平淡无奇如同白开水一般。

第一行代码从堆上分配一段内存用来构建data对象,后两行用来初始化各个字段,简单吧。

假设此时程序在执行到第3行时机器断电,或者系统崩溃,那么此时内存会一扫而空,不会再有mydata的数据存在,小风哥我在这家银行不会有任何信息存在,当然还包括我的1亿巨款。

但假设该程序不是运行在普通内存而是持久内存当中会怎么样呢?

让我们再来看一下这段代码:

struct data *xfg = new data();
xfg->name = "xiaofengge";
xfg->money = 100000000;

假设在执行到第三行时机房断电了,注意,此时程序的数据都保存在持久内存中,那么此时断电小风哥的账户名称已经保存下来了,还不错,但最重要的1亿元却没有保存下来,那么当程序再次启动时小风哥就只能看到一个空的账户了。

现在你应该意识到基于持久内存进行编程的难点了吧。

基于持久化内存编程的复杂性

程序员在基于持久内存进行编程时需要时刻意识到这是一块内存,因此需要维护多线程访问的一致性,但与此同时这又是一块存储设备,需要维护在运行时以及持久化的数据一致性。

基于此现状,当前的支持持久内存的库都支持这样一种特性,也即原子特性,atomic。

原子在不用的应用场景下有不同的语义,在多线程编程场景下,原子也即意味着除了当前线程之外没有任何一个线程更看到数据的中间状态,换句话说就是不会有多个线程同时去修改一块内存。

但原子在持久内存下的语言就不太一样了,原子在这种场景下的语义是说不管在任何时刻断电也好、程序崩溃也好,当程序重启后不会看到数据的中间状态,该数据要么已经正确的持久化要么还没有开始持久化。

这里的数据和上面一样,小到一个字节,大到一个非常复杂的结构体。

多线程中的锁只能保证内存更新的原子性,但不能保证数据持久化的原子性

解决方案

为实现数据持久化原子性,持久内存编程SDK通常从数据中借鉴一个叫做事务的概念,transaction。

事务的意思是这样的:假设某个数据可能需要经过A、B、C、D几个步骤才能修改完毕,我们把这四个步骤打包放到事务中,那么事务就可以确保这四个步骤要么全部执行完毕,要么全部都不去执行。这样即使在任意一个步骤断电或者程序崩溃都不会影响到数据的一致性问题。

如果你对持久化内存编程非常感兴趣,关注公众号码农的荒岛求生并回复pmem即可下载详细编程资料。

值得注意的是,程序员常用的磁盘flush操作只是确保当该函数执行完成后数据已经被写到了磁盘,但flush并不等同于事务,因为如果在flush过程中如果断电或者系统崩溃那么数据就处于薛定谔状态,可能数据已经被完全写到磁盘了,也可能只写了一部分,当然,也可能什么都没写。

有的同学可能不理解为什么读写磁盘时要flush,原因在于操作系统会把内存当做磁盘的缓存用,出于性能的考虑你写到磁盘中的数据并不会立即刷入磁盘,而是会有一个异步任务来完成写磁盘操作,这就是Linux下的page cache机制,关于这类机制的实现原理请参见博主的深入理解操作系统,关注公众号码农的荒岛求生并回复操作系统即可。

总结

本文介绍一种全新的内存设备,这类设备可以被操作系统识别为内存,但又像磁盘一样断电后内容不丢失,这类设备尤其适用于对内存容量要求高以及程序启动时间长的场景。

但,这类设备在编程上对程序员来说是一大挑战,这种持久内存在未来是否会成为主流也尚待观察。

我是小风哥,希望这篇文章能给大家一些启发。

-End-

最近有一些小伙伴,让我帮忙找一些 面试题 资料,于是我翻遍了收藏的 5T 资料后,汇总整理出来,可以说是程序员面试必备!所有资料都整理到网盘了,欢迎下载!

点击????卡片,关注后回复【面试题】即可获取

在看点这里好文分享给更多人↓↓

颠覆三观,内存真能当SSD用了!!!相关推荐

  1. ssd在linux下专为内存设备,linux下SSD优化

    SSD损坏的原因是一个点写的次数过多了,优化的方式就是减少总的写入量. 1.更改BLOS中磁盘读写设置为AHCI,改为顺序写,提高读写效率 2.将SSD分一个区,如果是多个区就要注意文件系统的块开头和 ...

  2. kotlin 协程异常处理机制颠覆三观

    转载请标明出处:http://blog.csdn.net/zhaoyanjun6/article/details/121938761 本文出自[赵彦军的博客] 文章目录 协程树与结构化并发 协程作用域 ...

  3. 标准表达式中数据类型不匹配_三观不同的人在一起有多累?三观一致的标准,不进行三观测试真不知道!人生观测试,价值观测试,世界观测试题推荐!超准三观匹配度测试!...

    生活中有很多不确定因素,有着很多悲欢离合与挑战.想驾驭生活吗?最好的方式是将自己打造成生活的英雄.但英雄是个矛盾体,因为英雄既有利他精神,常常心系天下:又有着孤傲一面,常常单枪匹马.一个人要想成为一个 ...

  4. 18张颠覆三观的照片!

    A10攻击机上的子弹,每秒打出70发 艾菲尔铁塔,从底部往上看 360度的彩虹 最牛停车场(大众沃尔夫斯堡汽车厂) 蜂窝 土豪之国沙特的农田 你看到的是美女还是两位接吻者? 角膜移植后的样子 最轻的材 ...

  5. 5招在不添加内存、显卡、ssd前提下有效提升windows系统pc性能

    Windows系统提升运行状态的方法 1.系统盘瘦身: (1)   桌面文件:右击桌面文件(非快捷标志)查看文件位置,默认为C盘: 按照路径找到"桌面"或者"Deskto ...

  6. 京东推出AI法律机器人 但机器人颠覆律师行业真那么容易吗?

    9月17日,备受瞩目的2018世界人工智能大会在上海正式召开.这次大会集结了不少科技巨头的大佬,马云.马化腾.李彦宏.雷军等都悉数出席.不过,最近身陷丑闻的刘强东却缺席了这次的大会.虽说京东CEO没出 ...

  7. 震撼!颠覆三观的18张照片,告诉我第7张你看到了啥?

    A10攻击机上的子弹,每秒打出70发 艾菲尔铁塔,从底部往上看 360度的彩虹 最牛停车场(大众沃尔夫斯堡汽车厂) 蜂窝 土豪之国沙特的农田 你看到的是美女还是两位接吻者? 角膜移植后的样子 最轻的材 ...

  8. ssd测试软件和实际 速度,测出真相!实测CPU/内存对SSD性能的影响

    1解析CPU,内存和硬盘三者关系 [PConline 评测]不同于传统的机械硬盘,固态硬盘的组成很"简单",主控+闪存+PCB+外壳(缓存有些SSD直接省去).那实际影响SSD性能 ...

  9. 阿里终面:为什么SSD不能当做内存用?

    在回答这个问题之前我们先去某东上逛一圈. 输入"SSD"随便找到销量比较高的一项,在商品详情页上有这样的描述: 注意图片上显示的规格,读速高达3.5GB/s,真实情况下稍差点(尤其 ...

  10. RocksDB随机读性能是同门SSD近10倍!傲腾持久内存实力炸裂!

    来源:英特尔数据中心 众所周知,英特尔® 傲腾™ 持久内存(以下简称PMem)是一款近年来少见的,在性能.容量和数据持久性上都让人眼前一亮的创新产品,而英特尔每每提及它时,都会用"颠覆传统内 ...

最新文章

  1. 高德API+Python解决租房问题
  2. Y项目逸事之中国人设计的全球模板
  3. FlycoTabLayout使用
  4. 关于realarm S5P4418的u-boot显示内存大小问题解决方法
  5. SQL SERVER读书笔记:nolock
  6. python 向量_关于Python中的向量相加和numpy中的向量相加效率对比
  7. python三方库之BeautifuSoup
  8. webservice studio 参数是DataSet时不支持中文 解决方法
  9. 配对(套利)交易之二,符合配对规则回测
  10. PHP用301重定向根域名到www域名
  11. Windwalker —— 企业级 PHP 应用开发框架
  12. 文件管理器之字符和编码
  13. 【静态ip保姆级教程他来了】
  14. pyspider爬取tripadvisor
  15. meshLab裁剪网格
  16. Postman下载与安装操作步骤【超详细】
  17. 计算机串口(RS232)的针脚定义
  18. 每个人都可以做到:月入30000的秘籍!
  19. win7打开计算机一片空白,Win7系统打开文件夹查看选项发现一片空白怎么办
  20. Mapper的xml文件基础语法笔记,增删改查,遍历

热门文章

  1. JDBC中的Statement和PreparedStatement的差别
  2. linux configure使用方法
  3. 6.828 - lab3
  4. python复制图片文件_python批量复制图片到另一个文件夹
  5. java工程师的素质模型,优秀程序员必备的四项能力
  6. SIP - FreeSwitch 安装 编译
  7. mysql字符串多行字符串数组_MySQL从跨行任意长的字符串数组中获取不同的值
  8. 8plus基带电源供电线路_iPhone7显示手机无服务还有感叹号,基带通病问题,你中招了吗?...
  9. QT的TreeWidget遍历文件夹并且显示(递归实现)
  10. #ifndef HeaderName_h #define HeaderName_h #endif 使用详解