服务器三大体系 SMP、NUMA、MPP

“服务器三大体系 SMP、NUMA、MPP” https://blog.csdn.net/ZhipingXi/article/details/78133096 服务器三大体系 SMP、NUMA、MPP zhipingxi 2017-09-29 13:50:15 2236 收藏 5 分类专栏: Operating System 文章标签: 服务器 系统架构 numa smp mpp 系统架构来看,目前的商用服务器大体可以分为三类 对称多处理器结构(SMP: Symmetric Multi-Processor); 非一致存储访问结构(NUMA: Non-Uniform Memory Access); 海量并行处理结构(MPP: Massive Parallel Processing); 共享存储型多处理机有两种模型 均匀存储器存取 (Uniform-Memory-Access,简称UMA) 模型 非均匀存储器存取 (Nonuniform-Memory-Access,简称NUMA) 模型 SMP(Symmetric Multi-Processor) 所谓对称多处理器结构,是指服务器中多个CPU对称工作,无主次或从属关系。各CPU共享相同的物理内存,每个 CPU访问内存中的任何地址所需时间是相同的,因此SMP也被称为一致存储器访问结构(UMA: Uniform Memory Access)。对SMP服务器进行扩展的方式包括增加内存、使用更快的CPU、增加CPU、扩充I/O(槽口数与总线数)以及添加更多的外部设备(通常是磁盘存储)。 SMP服务器的主要特征是共享,系统中所有资源(CPU、内存、I/O等)都是共享的。也正是由于这种特征,导致了SMP服务器的主要问题,那就是它的扩展能力非常有限。对于SMP服务器而言,每一个共享的环节都可能造成SMP服务器扩展时的瓶颈,而最受限制的则是内存。由于每个CPU必须通过相同的内存总线访问相同的内存资源,因此随着CPU数量的增加,内存访问冲突将迅速增加,最终会造成CPU资源的浪费,使 CPU性能的有效性大大降低。实验证明,SMP服务器CPU利用率最好的情况是2至4个CPU。 图1.SMP服务器CPU利用率状态 NUMA(Non-Uniform Memory Access) 由于SMP在扩展能力上的限制,人们开始探究如何进行有效地扩展从而构建大型系统的技术,NUMA就是这种努力下的结果之一。利用NUMA技术,可以把几十个CPU(甚至上百个CPU)组合在一个服务器内。其CPU模块结构如图2所示: 图2.NUMA服务器CPU模块结构 NUMA服务器的基本特征是具有多个CPU模块,每个CPU模块由多个CPU(如4个)组成,并且具有独立的本地内存、I/O槽口等。由于其节点之间可以通过互联模块(如称为Crossbar Switch)进行连接和信息交互,因此每个CPU可以访问整个系统的内存(这是NUMA系统与MPP系统的重要差别)。显然,访问本地内存的速度将远远高于访问远地内存(系统内其它节点的内存)的速度,这也是非一致存储访问NUMA的由来。由于这个特点,为了更好地发挥系统性能,开发应用程序时需要尽量减少不同CPU模块之间的信息交互。利用NUMA技术,可以较好地解决原来SMP系统的扩展问题,在一个物理服务器内可以支持上百个CPU。比较典型的NUMA服务器的例子包括HP的Superdome、SUN15K、IBMp690等。 但NUMA技术同样有一定缺陷,由于访问远地内存的延时远远超过本地内存,因此当CPU数量增加时,系统性能无法线性增加。如HP公司发布Superdome服务器时,曾公布了它与HP其它UNIX服务器的相对性能值,结果发现,64路CPU的Superdome (NUMA结构)的相对性能值是20,而8路N4000(共享的SMP结构)的相对性能值是6.3。从这个结果可以看到,8倍数量的CPU换来的只是3倍性能的提升。 MPP(Massive Parallel Processing) 和NUMA不同,MPP提供了另外一种进行系统扩展的方式,它由多个SMP服务器通过一定的节点互联网络进行连接,协同工作,完成相同的任务,从用户的角度来看是一个服务器系统。其基本特征是由多个SMP服务器(每个SMP服务器称节点)通过节点互联网络连接而成,每个节点只访问自己的本地资源(内存、存储等),是一种完全无共享(Share Nothing)结构,因而扩展能力最好,理论上其扩展无限制,目前的技术可实现512个节点互联,数千个CPU。目前业界对节点互联网络暂无标准,如 NCR的Bynet,IBM的SPSwitch,它们都采用了不同的内部实现机制。但节点互联网仅供MPP服务器内部使用,对用户而言是透明的。 在MPP系统中,每个SMP节点也可以运行自己的操作系统、数据库等。但和NUMA不同的是,它不存在异地内存访问的问题。换言之,每个节点内的CPU不能访问另一个节点的内存。节点之间的信息交互是通过节点互联网络实现的,这个过程一般称为数据重分配(Data Redistribution)。 但是MPP服务器需要一种复杂的机制来调度和平衡各个节点的负载和并行处理过程。目前一些基于MPP技术的服务器往往通过系统级软件(如数据库)来屏蔽这种复杂性。举例来说,NCR的Teradata就是基于MPP技术的一个关系数据库软件,基于此数据库来开发应用时,不管后台服务器由多少个节点组成,开发人员所面对的都是同一个数据库系统,而不需要考虑如何调度其中某几个节点的负载。 NUMA与MPP的区别 ...

2 min · 219 words · -

宾语从句(Object Clause)

宾语从句(Object Clause) 在句子中起宾语作用的从句叫做宾语从句.宾语从句分为三类:动词的宾语从句,介词的宾语从句和形容词的宾语从句. 时态: 1.主句用一般现在时,从句可用任意时态。 2.主句用过去时,从句用过去某个时态。 3.主句用过去时,从句是真理时,只用一般现在时。 一、宾语从句的连接词 从属连词 连接宾语从句的从属连词主要有that,if,whether. that引导表示陈述句的宾语从句,而if和whether引导表示“是否”的宾语从句. He told me that he would go to the college the next year 他告诉我他下一年上大学. I don’t know if there will be a bus any more. 我不知道是否还会有公交车. Nobody knew whether he could pass the exam. 没人知道他是否会通过考试. 连接代词 连接代词主要有who, whom ,whose ,what ,whoever ,whomever ,whosever, whatever, whichever等. 关系代词what引导 连接代词一般指疑问,但what, whatever除了指疑问外,也可以指陈述. Do you know who has won Red Alert game? 你知道谁赢了这一局红警游戏吗? I don’t know whom you should depend on. ...

7 min · 1344 words · -

字体 , 编程字体, 等宽字体

“字体 , 编程字体, 等宽字体” ubunti install 微软雅黑 sudo apt-get install ttf-mscorefonts-installer # 更新字体缓存 sudo fc-cache -f -v 编程字体, 等宽字体 对于程序员来说,好的字体应该满足的基本条件: 字母和数字易于分辨,如: 英文字母 o 和 阿拉伯数字 0, 或者 英文字母 l 和 阿拉伯数字 1 ,两个单引号 ’’ 和双引号 “. 字体等宽,保持对齐,美观漂亮 免费开源 Source Code Pro 是 Adobe 公司号称最佳的编程字体。而且还是开源的。 它非常适合用于阅读代码,支持 Linux、Mac OS X 和 Windows 等操作系统,而且无论商业或个人都可以免费使用。 作者: jingr1 链接: https://www.jianshu.com/p/1d5e1aaeb3f6 来源: 简书 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。 https://www.archlinux.org/packages/extra/any/adobe-source-code-pro-fonts/ jetbrain 字体 JetBrain Mono yay -S ttf-jetbrains-mono FiraCode https://github.com/tonsky/FiraCode 等宽字体 status { /width: auto;/ ...

1 min · 90 words · -

中断, interrupts

“中断, interrupts” IRQ: Interrupt ReQuest, 中断请求 IDT,Interrupt Descriptor Table,中断描述符表 中断/interrupts 中断指当出现需要时,CPU暂时停止当前程序的执行转而执行处理新情况的程序和执行过程。即在程序运行过程中,系统出现了一个必须由CPU立即处理的情况,此时,CPU暂时中止程序的执行转而处理这个新的情况的过程就叫做中断。 为什么需要中断 如果让内核定期对设备进行轮询,以便处理设备请求,那会做很多无用功,因为外设的处理速度一般慢于CPU,而CPU不能一直等待外部事件。所以能让设备在需要内核时主动通知内核,会是一个聪明的方式,这便是中断。 https://blog.csdn.net/oathevil/article/details/6007655 中断分类 外中断 由 CPU 执行指令以外的事件引起,如 I/O 完成中断,表示设备输入/输出处理已经完成,处理器能够发送下一个输入/输出请求。此外还有时钟中断、控制台中断等。 异常 由 CPU 执行指令的内部事件引起,如非法操作码、地址越界、算术溢出等。 陷入 在用户程序中使用系统调用 中断是什么 中断的汉语解释是半中间发生阻隔、停顿或故障而断开。那么,在计算机系统中,我们为什么需要"阻隔、停顿和断开"呢? 举个日常生活中的例子,比如说我正在厨房用煤气烧一壶水,这样就只能守在厨房里,苦苦等着水开——如果水溢出来浇灭了煤气,有可能就要发生一场灾难了。等啊等啊,外边突然传来了惊奇的叫声"怎么不关水龙头?“于是我惭愧的发现,刚才接水之后只顾着抱怨这份无聊的差事,居然忘了这事,于是慌慌张张的冲向水管,三下两下关了龙头,声音又传到耳边,“怎么干什么都是这么马虎?"。伸伸舌头,这件小事就这么过去了,我落寞的眼神又落在了水壶上。 门外忽然又传来了铿锵有力的歌声,我最喜欢的古装剧要开演了,真想夺门而出,然而,听着水壶发出"咕嘟咕嘟"的声音,我清楚: 除非等到水开,否则没有我享受人生的时候。 这个场景跟中断有什么关系呢? 如果说我专心致志等待水开是一个过程的话,那么叫声、电视里传出的音乐不都让这个过程"半中间发生阻隔、停顿或故障而断开"了吗?这不就是活生生的"中断"吗? 在这个场景中,我是唯一具有处理能力的主体,不管是烧水、关水龙头还是看电视,同一个时间点上我只能干一件事情。但是,在我专心致志干一件事情时,总有许多或紧迫或不紧迫的事情突然出现在面前,都需要去关注,有些还需要我停下手头的工作马上去处理。只有在处理完之后,方能回头完成先前的任务,“把一壶水彻底烧开!” 中断机制不仅赋予了我处理意外情况的能力,如果我能充分发挥这个机制的妙用,就可以"同时"完成多个任务了。回到烧水的例子,实际上,无论我在不在厨房,煤气灶总是会把水烧开的,我要做的,只不过是及时关掉煤气灶而已,为了这么一个一秒钟就能完成的动作,却让我死死地守候在厨房里,在10分钟的时间里不停地看壶嘴是不是冒蒸气,怎么说都不划算。我决定安下心来看电视。当然,在有生之年,我都不希望让厨房成为火海,于是我上了闹钟,10分钟以后它会发出"尖叫”,提醒我炉子上的水烧开了,那时我再去关煤气也完全来得及。我用一个中断信号——闹铃——换来了10分钟的欢乐时光,心里不禁由衷地感叹: 中断机制真是个好东西。 正是由于中断机制,我才能有条不紊地"同时"完成多个任务,中断机制实质上帮助我提高了并发"处理"能力。它也能给计算机系统带来同样的好处: 如果在键盘按下的时候会得到一个中断信号,CPU就不必死守着等待键盘输入了;如果硬盘读写完成后发送一个中断信号,CPU就可以腾出手来集中精力"服务大众"了——无论是人类敲打键盘的指尖还是来回读写介质的磁头,跟CPU的处理速度相比,都太慢了。没有中断机制,就像我们苦守厨房一样,计算机谈不上有什么并行处理能力。 跟人相似,CPU也一样要面对纷繁芜杂的局面——现实中的意外是无处不在的——有可能是用户等得不耐烦,猛敲键盘;有可能是运算中碰到了0除数;还有可能网卡突然接收到了一个新的数据包。这些都需要CPU具体情况具体分析,要么马上处理,要么暂缓响应,要么置之不理。无论如何应对,都需要CPU暂停"手头"的工作,拿出一种对策,只有在响应之后,方能回头完成先前的使命,“把一壶水彻底烧开!” 先让我们感受一下中断机制对并发处理带来的帮助。 让我们用程序来探讨一下烧水问题,如果没有"中断” (注意,我们这里只是模仿中断的场景,实际上是用异步事件——消息——处理机制来展示中断产生的效果。毕竟,在用户空间没有办法与实际中断产生直接联系,不过操作系统为用户空间提供的异步事件机制,可以看作是模仿中断的产物) ,设计如下: void StayInKitchen() { bool WaterIsBoiled = false; while ( WaterIsBoiled != true ) { bool VaporGavenOff = false; if (VaporGavenOff ) WaterIsBoiled = true; else WaterIsBoiled = false; } // 关煤气炉 printf("Close gas oven./n"); // 一切安定下来,终于可以看电视了,10分钟的宝贵时间啊,逝者如斯夫… watching_tv(); return; } 可以看出,整个流程如同我们前面描述的一样,所有工作要顺序执行,没有办法完成并发任务。 ...

4 min · 805 words · -

xorm

“xorm” generate golang code /home/wiloon/workspace/my-projects/reverse/reverse -f custom-business.yml https://gitea.com/xorm/xorm https://gitea.com/xorm/reverse https://studygolang.com/articles/27223

1 min · 10 words · -

user design

“user design” https://segmentfault.com/q/1010000005013911

1 min · 3 words · -

UPS

“UPS” 后备式UPS 平时处于蓄电池充电状态, 在停电时逆变器紧急切换到工作状态,将电池提供的直流电转变为稳定的交流电输出,因此后备式UPS也被称为离线式UPS。后备式UPS电源的优点是: 运行效率高、噪音低、价格相对便宜,主要适用于市电波动不大,对供电质量要求不高的场合,比较适合家庭使用。然而这种UPS存在一个切换时间问题,因此不适合用在关键性的供电不能中断的场所。不过实际上这个切换时间很短,一般介于2 至10毫秒,而计算机本身的交换式电源供应器在断电时应可维持10 毫秒左右,所以个人计算机系统一般不会因为这个切换时间而出现问题。后备式UPS一般只能持续供电几分钟到几十分钟,主要是让您有时间备份数据,并尽快结束手头工作,其价格也较低。对不是太关键的电脑应用,比如个人家庭用户,就可配小功率的后备式UPS。 在线式UPS 这种UPS一直使其逆变器处于工作状态,它首先通过电路将外部交流电转变为直流电,再通过高质量的逆变器将直流电转换为高质量的正弦波交流电输出给计算机。在线式UPS在供电状况下的主要功能是稳压及防止电波干扰; 在停电时则使用备用直流电源 (蓄电池组) 给逆变器供电。由于逆变器一直在工作,因此不存在切换时间问题,适用于对电源有严格要求的场合。在线式UPS不同于后备式的一大优点是供电持续长,一般为几个小时, 也有大到十几个小时的, 它的主要功能是可以让您在停电的情况可像平常一样工作,显然,由于其功能的特殊,价格也明显要贵一大截。这种在线式UPS比较适用于计算机、交通、银行、证券、通信、医疗、工业控制等行业,因为这些领域的电脑一般不允许出现停电现象。 在线互动式UPS 这是一种智能化的UPS,所谓在线互动式UPS,是指在输入市电正常时, UPS的逆变器处于反向工作 (即整流工作状态) ,给电池组充电;在市电异常时逆变器立刻转为逆变工作状态,将电池组电能转换为交流电输出,因此在线互动式UPS也有转换时间。同后备式UPS相比,在线互动式UPS的保护功能较强,逆变器输出电压波形较好,一般为正弦波,而其最大的优点是具有较强的软件功能,可以方便地上网,进行UPS的远程控制和智能化管理。可自动侦测外部输入电压是否处于正常范围之内, 如有偏差可由稳压电路升压或降压, 提供比较稳定的正弦波输出电压。而且它与计算机之间可以通过数据接口 (如RS-232 串口) 进行数据通讯,通过监控软件,用户可直接从电脑屏幕上监控电源及UPS状况,简化、方便管理工作,并可提高计算机系统的可靠性。这种UPS集中了后备式UPS效率高和在线式UPS供电质量高的优点,但其稳频特性能不是十分理想,不适合做常延时的UPS电源。 https://zhuanlan.zhihu.com/p/45168295 灵敏度 所谓灵敏度,就是指UPS对电网的敏感程度,灵敏度越高,对电网越敏感,对电网质量要求也就越高。对于电网质量较差的地方或使用发电机的地方,如果灵敏度高,可能会造成UPS一直在市电供电和电池供电状态间来回切换,或导致UPS一直工作在电池状态,对此,可适当降低灵敏度,以期在这种供电环境中UPS能正常工作,节省电池电量,为负载提供长延时保护。

1 min · 27 words · -

uclibc, glibc

“uclibc, glibc” uClibc 和Glibc 并不相同,两者有许多不同之处,而且以下不同有可能给你带来一些问题. uClibc比Glibc小,虽然uClibc和Glibc在已有的接口上是兼容的,而且采用uClibc编译应用程序比采用Glibc编译应用程序要更方便,但是uClibc并没有包括Glibc中的所有接口实现,因此有些应用可能在uClibc中不能编译。 uClibc在可配置性上比Glibc要好。 uClibc 并不能保证发布的库二进制兼容旧版本uClibc库。当一个新的版本uClibc库被发布,则可能需要也可能不需要重新编译应用程序。 在Glibc中调用malloc(0),将返回一个有效的指针,然而在uClibc中调用malloc(0),则返回NULL指针。根据在SuSv3中关于malloc(0)的行为的定义,两个库的实现都是正确的。对于调用relloc(NULL,0),两个库的实现也不同。个人感觉Glibc的如此实现不是特别安全。 Glibc中malloc的实现可以通过MALLOC_CHECK_ 环境变量调节。这个方法主要用于malloc调试。这些扩展的malloc调试特性在uClibc中是不可用的。在Linux上有许多有些的malloc调试功能的库(如: dmalloc,electric fence,valgrind等)比Glibc中的扩展的malloc调试功能更好用。因此uClibc中去掉这些功能特性并不会有多打损失。 uClibc没有提供用于数据接口的库(libdb)。 uClibc不支持NSS(/lib/libnss_*),在这方面Glibc更容易支持不同方式的认证和DNS解析。uClibc仅仅支持采用flat口令文件或者shadow口令文件存储授权信息。如果需要比这些更复杂的的授权,可以编译安装pam。 uClibc中的libresolv库仅仅是一个桩。Glibc的libresolv库中的部分并不是全部的功能uClibc都提供,许多函数都没有实现。 提供网络信息服务支持(NIS)libnsl库(最初被称为黄页YP),被SUN扩展为发明为RPC并用于网络共享Unix口令文件 。个人认为NIS是一个令人厌恶的东西并应该使用。因此,在实现相同的功能情况下采用ldap比NIS更有效。uClibc虽然提供一个桩libnsl,但并不支持NIS。我们因此也不提供在Glibc下提供的位于/usr/include/rpcsvc里的头文件。 uClibc的区域支持并不是100%的完全。正在这方面努力 uClibc的数据功能函数库内部仅仅支持long double,设置对于long double的支持也是非常有限。与此对应的只实现了较少的数学函数。如果应用程序采用double类型,则会程序会运行得较好。 uClibc的libcrpt库不支持可重入crypt_r,setkey_r和encrypt_r,因为这些也不是SuSv3所规定的。 uClibc直接采用内核的数据类型去定义大多数透明的数据类型。 uClibc支持采用linux内核结构特有的结构体"struct stat"。 uClibc的运行时库librt当前缺少aio接口、全部的时钟接口和共享内存接口(仅仅实现定时器接口和消息队列接口) 版权声明: 本文为CSDN博主「zengwh」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。 原文链接: https://blog.csdn.net/zengwh/article/details/1482418

1 min · 34 words · -

UART

“UART” 串口通信 UART 异步收发传输器(Universal Asynchronous Receiver/Transmitter),通常称作UART,是一种异步收发传输器。 首先先来介绍以下同步和异步通信,同步是指,发送方发出数据后,等接收方发回响应以后才发下一个数据包的通讯方式;异步是指,发送方发出数据后,不等接收方发回响应,接着发送下个数据包的通讯方式。换句话说,同步通信是阻塞方式,异步通信是非阻塞方式。在常见通信总线协议中,I2C,SPI属于同步通信而UART属于异步通信。同步通信的通信双方必须先建立同步,即双方的时钟要调整到同一个频率,收发双方不停地发送和接收连续的同步比特流。异步通信在发送字符时,发送端可以在任意时刻开始发送字符,所以,在UART通信中,数据起始位和停止位是必不可少的。 硬件层 常用RS-232标准,这里不详细解释,主要是对应设备的Tx线和Rx线要对应正确。 协议层 协议层中,规定了数据包的内容,它由起始位、主体数据、校验位以及停止位组成,通信双方的数据包格式要约定一致才能正常收发数据 。 波特率: 异步通信中由于没有时钟信号,所以2个通信设备需约定好波特率,常见的有4800、9600、115200等。 通信的起始和停止信号: 串口通信的一个数据包从起始信号开始,知道停止信号结束。数据包的起始信号由一个逻辑0的数据位表示,而数据包的停止信号可由0.5、1、1.5或2个逻辑1的数据位表示,只要双方约定一致即可。 有效数据: 在数据包的起始位之后紧接着的就是要传输的主体数据内容,也称为有效数据,有效数据的长度常被约定为8位或9位长。 数据校验: 在有效数据之后,有一个可选的数据校验位。由于数据通信相对容易受到外部干扰导致传输数据出现偏差,可以在传输过程加上校验位来解决这个问题。校验方法有奇校验(odd)、偶校验(even)、0校验(space)、1校验(mark)以及无校验(noparity)。 奇校验要求有效数据和校验位中"1"的个数为奇数,比如一个 8 位长的有效数据为: 01101001,此时总共有 4 个"1",为达到奇校验效果,校验位为"1",最后传输的数据将是 8 位的有效数据加上 1 位的校验位总共 9 位。偶校验与奇校验要求刚好相反,要求帧数据和校验位中"1"的个数为偶数,比如数据帧: 11001010,此时数据帧"1"的个数为 4 个,所以偶校验位为"0"。0 校验是不管有效数据中的内容是什么,校验位总为"0",1 校验是校验位总为"1"。 https://zhuanlan.zhihu.com/p/136806005

1 min · 38 words · -

TLB

“TLB” TLB是translation lookaside buffer的简称。首先,我们知道MMU的作用是把虚拟地址转换成物理地址。虚拟地址和物理地址的映射关系存储在页表中,而现在页表又是分级的。64位系统一般都是3~5级。常见的配置是4级页表,就以4级页表为例说明。分别是PGD、PUD、PMD、PTE四级页表。在硬件上会有一个叫做页表基地址寄存器,它存储PGD页表的首地址。MMU就是根据页表基地址寄存器从PGD页表一路查到PTE,最终找到物理地址(PTE页表中存储物理地址)。这就像在地图上显示你的家在哪一样,我为了找到你家的地址,先确定你是中国,再确定你是某个省,继续往下某个市,最后找到你家是一样的原理。一级一级找下去。这个过程你也看到了,非常繁琐。如果第一次查到你家的具体位置,我如果记下来你的姓名和你家的地址。下次查找时,是不是只需要跟我说你的姓名是什么,我就直接能够告诉你地址,而不需要一级一级查找。四级页表查找过程需要四次内存访问。延时可想而知,非常影响性能。页表查找过程的示例如下图所示。以后有机会详细展开,这里了解下即可。 TLB Translation Look-aside Buffer 地址变换高速缓存 地址转换后备缓冲器 学习理解TLB (Translation Look-aside Buffer) 地址变换高速缓存 前言: 本文学习思路是: 存在缘由 –> 存在好处 –> 定义性质 –> 具体分析 存在缘由: 由于地址映射 (从虚拟地址转换成物理地址) 需要的开销开大。 转换过程如下: 第一次访问内存是访问页表,取出虚拟页对应的物理页。 第二次访问内存是访问实际内存地址。 为了提高效率,现代CPU都包含了一个特殊Cache来跟踪最近使用过的地址变换,这个就是TLB。 明显好处: 如果有了TLB,那么地址转换变成如下过程: 第一次访问TLB,得到虚拟页对应的物理页 第二次访问的是内存,访问实际地址。 这样就省去了一次访问内存的时间,大大提高了效率。 概念概括: TLB英文全称: Translation Look-aside Buffer TLB中文全称: 地址变换高速缓存 TLB中文简称: 快表 TLB实际性质: 它是一种cache TLB的每一项中包含 有效位(valid)。现在的计算机基本都是使用虚拟存储器,简单来说就是假如你要打开一个很大的程序,它不会把所有的文件都加载进内存。当需要用的内容不在内存上时,它再去硬盘上找并加载到内存。故,有效位的作用就是,假如是0,就代表该页不在内存中,需要去硬盘中找。 引用位(reference)。由于TLB中的项数是一定的,所以当有新的TLB项需要进来但是又满了的话,如果根据LRU算法,就将最近最少使用的项替换成新的项。故需要引用位。同时要注意的是,页表中也有引用位。 脏位(dirty)。现在的计算机基本都是使用虚拟存储器,简单来说就是假如你要打开一个很大的程序,它不会把所有的文件都加载进内存。当需要用的内容不在内存上时,它再去硬盘上找并加载到内存。故脏位的作用就是,当内存上的某个块需要被新的块替换时,它需要根据脏位判断这个块之前有没有被修改过,如果被修改过,先把这个块更新到硬盘再替换,否则就直接替换。 物理页号。 过程描述如下: 首先,先去TLB中根据标志Tag寻找,假如找到了并且有效位是1,说明TLB命中了,那么直接就可以从TLB中获取该虚拟页号对应的物理页号。假如有效位是0,说明该页不在内存中,这时候就发生缺页异常,CPU需要先去外存中将该页调入内存并将页表和TLB更新。 假如在TLB中没有找到,那么就去页表 (Page Table) 中寻找 (以虚拟页号为索引) ,假如找到了并且有效位是1,那么就可以取出对应的物理页号。假如有效位是0,说明该页不在内存中,这时候就发生缺页异常,CPU需要先去外存中将该页调入内存并将页表和TLB更新。 假如在页表中没有找到,也是缺页。同意会执行上述的缺页处理。 (不管从哪获取到物理页号,都可以根据规则组拼成实际物理地址,然后就可以访存去数据啦) 引用位、脏位何时更新? 页表和TLB都有这两个标志位。如果是TLB命中,那么引用位就会被置1,当TLB或页表满时,就会根据该引用位选择适合的替换位置。如果TLB命中且这个访存操作是个写操作,那么脏位就会被置1,表明该页被修改过,当该页要从内存中移除时会先执行将该页写会外存的操作,保证数据被正确修改。 当TLB的某一项要被替换时,它的引用位和脏位都会被更新会页表。 补充: ...

2 min · 404 words · -

thundering herd, 惊群效应

“thundering herd, 惊群效应” 惊群效应是什么 惊群效应 (thundering herd) 是指多进程 (多线程) 在同时阻塞等待同一个事件的时候 (休眠状态) ,如果等待的这个事件发生,那么他就会唤醒等待的所有进程 (或者线程) ,但是最终却只能有一个进程 (线程) 获得这个时间的“控制权”,对该事件进行处理,而其他进程 (线程) 获取“控制权”失败,只能重新进入休眠状态,这种现象和性能浪费就叫做惊群效应。 惊群效应消耗了什么 Linux 内核对用户进程 (线程) 频繁地做无效的调度、上下文切换等使系统性能大打折扣。上下文切换 (context switch) 过高会导致 CPU 像个搬运工,频繁地在寄存器和运行队列之间奔波,更多的时间花在了进程 (线程) 切换,而不是在真正工作的进程 (线程) 上面。直接的消耗包括 CPU 寄存器要保存和加载 (例如程序计数器) 、系统调度器的代码需要执行。间接的消耗在于多核 cache 之间的共享数据。 为了确保只有一个进程 (线程) 得到资源,需要对资源操作进行加锁保护,加大了系统的开销。目前一些常见的服务器软件有的是通过锁机制解决的,比如 Nginx (它的锁机制是默认开启的,可以关闭) ;还有些认为惊群对系统性能影响不大,没有去处理,比如 Lighttpd。 https://www.cnblogs.com/Anker/p/7071849.html https://zhuanlan.zhihu.com/p/51251700 https://zhuanlan.zhihu.com/p/65843741

1 min · 48 words · -

STM32F407VG, STM32F407VGT6

“STM32F407VG, STM32F407VGT6” STM32F407VGT6 SMT32: 产品系列: 基于ARM的32位处理器 F: 产品类型: 通用类型 407: 产品子系列: … V: 引脚数: 100脚 G: 闪存容量: 1M T: 封装: LQFP 6: 温度范围: -40 ~ 85度 https://www.st.com/zh/microcontrollers-microprocessors/stm32f407-417.html Cortex™-M4内核 (具有浮点单元) 168 MHz 意法半导体90 nm工艺和ART加速器 2个USB OTG (其中一个支持HS) 音频: 专用音频PLL和2个全双工I²S 通信接口多达15个 (包括6个速度高达11.25 Mb/s的USART、3个速度高达45 Mb/s的SPI、3个I²C、2个CAN和1个SDIO) 模拟: 2个12位DAC、3个速度为2.4 MSPS或7.2 MSPS (交错模式) 的12位ADC 定时器多达17个: 频率高达168 MHz的16和32位定时器 可以利用支持Compact Flash、SRAM、PSRAM、NOR和NAND存储器的灵活静态存储器控制器轻松扩展存储容量 基于模拟电子技术的真随机数发生器 STM32F417还整合了加密/HASH处理器,为AES 128、192、256、3DES和HASH (MD5、SHA-1) 实现了硬件加速。 集成: STM32F417x系列具有512KB (仅限于WLCSP90封装) 1MB Flash和192KB SRAM,采用尺寸小至4 x 4.2 mm的64144引脚封装。 STM32F407/417产品系列具有512KB1MB Flash和192KB SRAM,采用尺寸小至10 x 10 mm的100 176引脚封装。 ...

1 min · 74 words · -

SCTP GRE

SCTP sctp和tcp的区别 作为一个传输层协议,SCTP兼有TCP及UDP两者的特点。SCTP可以称为是TCP的改进协议,但他们之间仍然存在着较大的差别。首先SCTP和TCP之间的最大区别是SCTP的连接可以是多宿主连接的,TCP则一般是单地址连接的。在进行SCTP建立连接时,双方均可声明若干IP地址(IPv4,Ipv6或主机名)通知对方本端所有的地址。若当前连接失效,则协议可切换到另一个地址,而不需要重新建立连接。 其次SCTP是基于消息流,而TCP则是基于字节流。所谓基于消息流,是指发送数据和应答数据的最小单位是消息包(chunk)。一个SCTP连接(Association)同时可以支持多个流(stream),每个流包含一系列用户所需的消息数据(chunk)。而TCP则只能支持一个流。在网络安全方面,SCTP增加了防止恶意攻击的措施。不同于TCP连接采用的三次握手机制,SCTP连接采用四次握手机制,有效的防止了类似于SYN Flooding的防范拒绝服务攻击。SCTP主要的贡献是对多重联外线路的支持,一个端点可以由多于一个IP地址组成,使得传输可在主机间或网卡间做到透明的网络容错备援。 https://www.cnblogs.com/elleniou/p/3342140.html GRE 通用路由封装协议GRE 提供了将一种协议报文封装在另一种协议报文中的机制,是一种三层隧道封装技术;可以对IPv4协议的数据报文进行再封装,使这些被封装的数据报文能够在另一个网络层协议(如IPv4)中传输;报文通过GRE隧道透明的传输,可以解决外网主动访问内网的问题;GRE可以封装组播数据和路由选择协议,结合IP Sec使用,从而保证语音、视频等组播业务的安全。 GRE实现机制简单,对隧道两端的设备负担小;GRE隧道可以有效利用了原有的网络架构,降低成本;GRE隧道扩展了跳数受限网络协议的工作范围,支持企业灵活设计网络拓扑;GRE隧道支持MPLS LDP,使用GRE隧道承载MPLS LDP报文,建立LDP LSP,实现MPLS骨干网的互通;GRE隧道将不连续的子网连接起来,用于组建VPN,实现企业总部和分支间安全的连接。 https://zhuanlan.zhihu.com/p/103214510

1 min · 15 words · -

redis, memcache

“redis, memcache” Redis 和 Memcached 都是基于内存的数据存储系统。Memcached是高性能分布式内存缓存服务,其本质上就是一个内存key-value数据库。Redis是一个开源的key-value存储系统。与Memcached类似,Redis将大部分数据存储在内存中,支持的数据类型包括: 字符串、哈希表、链表、集合、有序集合以及基于这些数据类型的相关操作。那么,Memcached与Redis有什么区别呢? 数据操作不同, Redis支持的数据类型要丰富得多 与Memcached仅支持简单的key-value结构的数据记录不同,Redis支持的数据类型要丰富得多。 Memcached基本只支持简单的key-value存储,不支持枚举,不支持持久化和复制等功能。 Redis支持服务器端的数据操作相比Memcached来说,拥有更多的数据结构和并支持更丰富的数据操作,支持list、set、sorted set、hash等众多数据结构,还同时提供了持久化和复制等功能。而通常在Memcached里,使用者需要将数据拿到客户端来进行类似的修改再set回去,这大大增加了网络IO的次数和数据体积。在Redis中,这些复杂的操作通常和一般的GET/SET一样高效。所以,如果需要缓存能够支持更复杂的结构和操作, Redis会是更好的选择。 内存管理机制不同 在Redis中,并不是所有的数据都一直存储在内存中的。这是和Memcached相比一个最大的区别。当物理内存用完时,Redis可以将一些很久没用到的value交换到磁盘。Redis只会缓存所有的key的信息,如果Redis发现内存的使用量超过了某一个阀值,将触发swap的操作,Redis根据“swappability = age*log(size_in_memory)”计算出哪些key对应的value需要swap到磁盘。然后再将这些key对应的value持久化到磁盘中,同时在内存中清除。这种特性使得Redis可以保持超过其机器本身内存大小的数据。 而Memcached默认使用Slab Allocation机制管理内存,其主要思想是按照预先规定的大小,将分配的内存分割成特定长度的块以存储相应长度的key-value数据记录,以完全解决内存碎片问题。 从内存利用率来讲,使用简单的key-value存储的话,Memcached的内存利用率更高。而如果Redis采用hash结构来做key-value存储,由于其组合式的压缩,其内存利用率会高于Memcached。 性能不同 由于Redis只使用单核,而Memcached可以使用多核,所以平均每一个核上Redis在存储小数据时比Memcached性能更高。而在100k以上的数据中,Memcached性能要高于Redis,虽然Redis也在存储大数据的性能上进行了优化,但是比起Memcached,还是稍有逊色。 集群管理不同 Memcached是全内存的数据缓冲系统,Redis虽然支持数据的持久化,但是全内存毕竟才是其高性能的本质。作为基于内存的存储系统来说,机器物理内存的大小就是系统能够容纳的最大数据量。如果需要处理的数据量超过了单台机器的物理内存大小,就需要构建分布式集群来扩展存储能力。 Memcached本身并不支持分布式,因此只能在客户端通过像一致性哈希这样的分布式算法来实现Memcached的分布式存储。相较于Memcached只能采用客户端实现分布式存储,Redis更偏向于在服务器端构建分布式存储。 持久性 redis支持数据落地持久化存储,可以将内存中的数据保持在磁盘中,重启的时候可以再次加载进行使用。 memcache不支持数据持久存储 小结: Redis和Memcached哪个更好? Redis更多场景是作为Memcached的替代者来使用,当需要除key-value之外的更多数据类型支持或存储的数据不能被剔除时,使用Redis更合适。如果只做缓存的话,Memcached已经足够应付绝大部分的需求,Redis 的出现只是提供了一个更加好的选择。总的来说,根据使用者自身的需求去选择才是最合适的。 It’s not uncommon to hear Redis compared to memcached, which is a very high- performance, key-value cache server. Like memcached, Redis can also store a mapping of keys to values and can even achieve similar performance levels as memcached. But the similarities end quickly—Redis supports the writing of its data to disk automatically in two different ways, and can store data in four structures in addition to plain string keys as memcached does. These and other differences allow Redis to solve a wider range of problems, and allow Redis to be used either as a primary database or as an auxiliary data- base with other storage systems. ...

1 min · 161 words · -

redis vm

“redis vm” 重点提示: Redis 的虚拟内存(VM) 目前不被提倡使用,Redis 2.4将是有虚拟内存特性的最新版本 (但它同样提示不鼓励使用虚拟内存) 。我们发现使用虚拟内存会有一些不足和问题。对于Redis的未来,至少目前在不考虑支持比RAM更大的数据库时,我们希望能提供最好的内存数据库 (持久化仍然在磁盘上) 。我们随后的成果将关注提供脚本,集群以及更好的持久化方面。 虚拟内存 Redis 虚拟内存这一特性将首次出现在Redis 2.0的一个稳定发布版中。目前Git上Redis 不稳定分支的虚拟内存 (从现在起称之为VM) 已经可以使用,并且经试验证明足够稳定。 简介 Redis遵循 key-value模型。同时key和value通常都存储在内存中。然而有时这并不是一个最好的选择,所以在设计过程中我们要求key必须存储在内存中 (为了保证快速查找) ,而value在很少使用时,可以从内存被交换出至磁盘上。 实际应用中,如果内存中有一个10万条记录的key值数据集,而只有10%被经常使用,那么开启虚拟内存的Redis将把与较少使用的key相对应的value转移至磁盘上。当客户端请求获取这些value时,他们被将从swap 文件中读回,并载入到内存中。 何时使用虚拟内存 在确定使用VM之前,请首先确认是否真的需要使用这一特性。Redis是一个磁盘备份,内存型数据库。使用Redis 的正确方法通常是使用足够大的RAM去装载所有数据。然而,有些场景下是无法做到这样的: 数据访问不均匀。只有很少部分的key被大量访问,而每一个key又有大量的数据要放入内存。 在不考虑数据读取方式以及value存储空间大小的前提下,仅由于没有足够的空间将所有数据放入内存。这种场景下,Redis可以被配置为在内存中存储key,在磁盘中存储value。此时key的查询操作较快,而value的读取则相对较慢。 谨记Redis的key是不做swap操作的,所以如果你的内存有大量的key和少量的value时,那么VM并不能解决你的问题。 然而当由于value占用空间较大 (如占用空间较多的strings以及含有大量元素的lists, sets 或者 hashes) 导致内存不足时,那么VM无疑是一个很好的选择。 有时你可以通过哈希表将相关的数据归组到一个key的相应字段,从而将“大量key与小存储的value”的问题转化为“少量key与大存储的value”的问题。例如你可以为每一个对象设置一个单独的key,并用哈希表的多个字段代表对象的不同属性,而非为对象的每一个属性设置一个单独的key。 VM 配置 VM的配置相对简单,可以根据需求设置最佳参数。通过编辑redis.conf来开启并配置VM。首先开启VM: vm-enabled yes 很多配置项可以改变VM的行为。事实上,为了获取最佳性能,你常常需要对配置做微调,而非使用默认参数。 vm-max-memory设置 vm-max-memory 指 Redis 在将value交换至磁盘 (进行swap操作) 之前有多大内存可使用。 通常,如果未达到内存上限,则不需要进行磁盘交换,Redis将所有对象放在内存中操作。然而一旦到达上限,将会有大量的对象被交换出内存至磁盘,以释放内存空间,直到低于限制。 交换过程 (swap操作) 中,首先被交换的对象是那些有着较大“年龄” (指未被访问的时长) 的对象,同时一个对象的“交换能力” (”swappability”) 与它在内存中大小的对数成正 (swappability = age*log(size_in_memory)) 。当两个对象有着相同的“年龄”时,占用空间较大的对象将会首先被交换出去。 提醒: 由于key不能被交换出内存,所以当仅由于key占用空间较多而达到内存上限时, Redis是不能通过改变 vm-max-memory 来解决问题的。 ...

2 min · 314 words · -

nvme

“nvme” https://zhuanlan.zhihu.com/p/135297463

1 min · 2 words · -

nats

“nats” https://nats.io/ podman podman run -d –name nats -p 4222:4222 -v /etc/localtime:/etc/localtime:ro nats https://zhuanlan.zhihu.com/p/40871363 nats 是一个开源的,云原生的消息系统。Apcera,百度,西门子,VMware,HTC 和爱立信等公司都有在使用。 核心基于EventMachine开发,原理是基于消息发布订阅机制,每台服务器上的每个模块会根据自己的消息类别向MessageBus发布多个消息主题,而同时也向自己需要交互的模块,按照需要的主题订阅消息。能够达到每秒8-11百万个消息,整个程序很小只有3M Docker image,它不支持持久化消息,如果你离线,你就不能获得消息。使用nats streaming可以做到持久化,缓存等功能。 NATS server nats提供了一个go编写的轻量级服务器。发行版包括二进制和docker镜像 NATS clients nats官方提供的客户端有Go,Node,Ruby,Java,C,C#,NGINX等。 NATS 设计目标 核心原则是性能,可伸缩和易用性。 高效 始终在线和可用 非常轻巧 支持多种质量的服务 支持各种消息传递模型和使用场景 NATS 使用场景 nats是一个简单且强大的消息系统,为支持现代云原生架构设计。由于可伸缩性的复杂性,nats旨在容易使用和实现,且能提供多种质量的服务。 一些适用nats的场景有: 高吞吐量的消息分散 —— 少数的生产者需要将数据发送给很多的消费者。 寻址和发现 —— 将数据发送给特定的应用实例,设备或者用户,也可用于发现并连接到基础架构中的实例,设备或用户。 命令和控制 (控制面板) —— 向程序或设备发送指令,并从程序/设备中接收状态,如SCADA,卫星遥感,物联网等。 负载均衡 —— 主要应用于程序会生成大量的请求,且可动态伸缩程序实例。 N路可扩展性 —— 通信基础架构能够充分利用go的高效并发/调度机制,以增强水平和垂直的扩展性。 位置透明 —— 程序在各个地理位置上分布者大量实例,且你无法了解到程序之间的端点配置详情,及他们所生产或消费的数据。 容错 使用nats-streaming的附加场景有: 从特定时间或顺序消费 持久性 有保证的消息投递 https://docs.nats.io/ https://github.com/nats-io/nats-server https://gcoolinfo.medium.com/comparing-nats-nats-streaming-and-nats-jetstream-ec2d9f426dc8

1 min · 66 words · -

nacos

“nacos” distro协议介绍 distro协议网上的资料比较少,因为它是阿里"自创的协议",通过源码总结一下distro协议的关键点: distro协议是为了注册中心而创造出的协议; 客户端与服务端有两个重要的交互,服务注册与心跳发送; 客户端以服务为维度向服务端注册,注册后每隔一段时间向服务端发送一次心跳,心跳包需要带上注册服务的全部信息,在客户端看来,服务端节点对等,所以请求的节点是随机的; 客户端请求失败则换一个节点重新发送请求; 服务端节点都存储所有数据,但每个节点只负责其中一部分服务,在接收到客户端的"写" (注册、心跳、下线等) 请求后,服务端节点判断请求的服务是否为自己负责,如果是,则处理,否则交由负责的节点处理; 每个服务端节点主动发送健康检查到其他节点,响应的节点被该节点视为健康节点; 服务端在接收到客户端的服务心跳后,如果该服务不存在,则将该心跳请求当做注册请求来处理; 服务端如果长时间未收到客户端心跳,则下线该服务; 负责的节点在接收到服务注册、服务心跳等写请求后将数据写入后即返回,后台异步地将数据同步给其他节点; 节点在收到读请求后直接从本机获取后返回,无论数据是否为最新。 https://juejin.im/post/6844904167924826119 https://developer.aliyun.com/article/723938 https://mp.weixin.qq.com/s?__biz=MzI5NjE2MDQwNg==&mid=2247483740&idx=1&sn=e1117bbe107b2e257fcf93cfe04b6218&chksm=ec49dca5db3e55b3305e955972278991e856371693d401f65b26ab055e2b236e6b12efe33753&token=169335499&lang=zh_CN&scene=21#wechat_redirect https://juejin.im/post/6844904167924826119 https://blog.csdn.net/fly910905/article/details/100023415 https://my.oschina.net/u/867417/blog/1865971

1 min · 21 words · -

MySQL自定义变量

“MySQL自定义变量” MySQL自定义变量的使用 用户自定义变量是一个容易被遗忘的MySQL特性,但是如果能用的好,发挥其潜力,在某些场景可以写出非常高效的查询语句。在查询中混合使用过程化和关系化逻辑的时候,自定义变量可能会非常有用。单纯的关系查询将所有的东西都当成无序的数据集合,并且一次性操作它们。MySQL则采用了更加程序化的处理方式。MySQL的这种方式有它的弱点,但如果能够熟练地掌握,则会发现其强大之处,而用户自定义变量也可以给这种方式带来很大的帮助 用户自定义变量是一个用来存储内容的临时容器,在连接MySQL的整个过程中都存在,可以使用下面的SET和SELECT语句来定义它们: SET @ONE := 1; SELECT @ONE; MySQL> SET @min_actor := (SELECT MIN(actor_id) FROM sakila.actor); MySQL> SET @last_week := CURRENT_DATE - INTERVAL 1 WEEK; 然后可以在任何可以使用表达式的地方使用这些自定义变量: SELECT … WHERE col <= @last_week; 在了解自定义变量的强大之前,我们先来看看它自身的一些属性和限制,看看在哪些场景下我们不能使用用户自定义变量: 使用自定义变量的查询,无法使用查询缓存 不能再使用常量或者标识符的地方使用自定义变量,例如表名、列名和LIMIT子句中。 用户自定义变量的生命周期是在一个连接中有效,所以不能用它们来做连接间的通信。 如果使用连接池或者持久化连接,自定义变量可能让看起来毫无关系的代码发生交互。 自定义变量的类型是一个动态类型。 MySQL优化器在某些场景下可能会将这些变量优化掉,这可能导致代码不按预想的方式运行。 赋值的顺序和赋值的时间点并不总是固定的,这依赖于优化器的决定。 赋值符号 :=的优先级非常低,所以需要注意,赋值表达式应该使用明确的括号。 使用未定义变量不会产生任何语法错误,如果没有意识到这一点,非常容易犯错。 https://www.jianshu.com/p/357a02fb2d64

1 min · 46 words · -

MySQL 显示行号,以及分组排序

“MySQL 显示行号,以及分组排序” CREATE TABLE my_tb ( id int(11) NOT NULL AUTO_INCREMENT, parent_code varchar(255) DEFAULT NULL, code varchar(255) DEFAULT NULL, PRIMARY KEY (id) ) ENGINE=InnoDB AUTO_INCREMENT=8 DEFAULT CHARSET=utf8; INSERT INTO `my_tb` ( `parent_code`, `code`) VALUES ('01', '001'); INSERT INTO `my_tb` ( `parent_code`, `code`) VALUES ('01', '002'); INSERT INTO `my_tb` ( `parent_code`, `code`) VALUES ('02', '001'); INSERT INTO `my_tb` ( `parent_code`, `code`) VALUES ('01', '003'); INSERT INTO `my_tb` ( `parent_code`, `code`) VALUES ('02', '002'); INSERT INTO `my_tb` ( `parent_code`, `code`) VALUES ('03', '001'); INSERT INTO `my_tb` ( `parent_code`, `code`) VALUES ('04', '001'); -- 生成 行号 select @r:=@r+1 as row_num , a.* from my_tb a ,(select @r:=0) b -- 生成 分组排序号 select @group_row:=CASE when @parent_code=a.parent_code then @group_row+1 else 1 end as groupRow, @parent_code:=a.parent_code as parent_code, a.code from my_tb a ,( select @group_row:=1, @parent_code:='') as b ORDER BY a.parent_code , a.code 查询结果 "groupRow" "parent_code" "code" "1" "01" "001" "2" "01" "002" "3" "01" "003" "1" "02" "001" "2" "02" "002" "1" "03" "001" "1" "04" "001" https://blog.csdn.net/kxjrzyk/article/details/58588000 ...

1 min · 163 words · -