安安 - 硬盘
type: channel
link: https://blog.90.vc/tag/%E7%A1%AC%E7%9B%98/
items: Kafka的集群部署实践及运维相关
items: RAID5 真的安全吗
items: Cache 和 Buffer 有什么区别？
items: vmware不重启扩展磁盘

Kafka的集群部署实践及运维相关
type: item
date: 2020-04-02T15:55:00+00:00
description: 一、Kafka的生产集群部署1.1 方案背景假设每天集群需要承载10亿数据。一天24小时，晚上12点到凌晨8点几乎没多少数据。使用二八法则估计，也就是80%的数据（8亿）会在16个小时涌入，而且8亿的80%的数据（6.4亿）会在这16个小时的20%时间（3小时）涌入。QPS计算公式：640000000 ÷ (3x60x60) = 60000，也就是说高峰期的时候Kafka集群要扛住每秒6万的并发。磁盘空间计算，每天10亿数据，每条50kb，也就是46T的数据。保存2个副本（在上一篇中也提到过其实两个副本会比较好，因为follower需要去leader那里同步数据，同步数据的过程需要耗费网络，而且需要磁盘空间，但是这个需要根据实际情况考虑），46 2 = 92T，保留最近3天的数据。故需要 92 3 = 276T1.2 QPS方面部署Kafka，Hadoop，MySQL···等核心分布式系统，一般建议直接采用物理机，抛弃使用一些低配置的虚拟机的想法。高并发这个东西，不可能是说，你需要支撑6万QPS，你的集群就刚好把这6万并发卡的死死的。加入某一天出一些活动让数据量疯狂上涨，那整个集群就会垮掉。但是，假如说你只要支撑6w QPS，单台物理机本身就能扛住4~5万的并发。所以这时2台物理机绝对绝对够了。但是这里有一个问题，我们通常是建议，公司预算充足，尽量是让高峰QPS控制在集群能承载的总QPS的30%左右（也就是集群的处理能力是高峰期的3~4倍这个样子），所以我们搭建的kafka集群能承载的总QPS为20万~30万才是安全的。所以大体上来说，需要5~7台物理机来部署，基本上就很安全了，每台物理机要求吞吐量在每秒4~5万条数据就可以了，物理机的配置和性能也不需要特别高。1.3 磁盘方面1.3.1 磁盘数量需要5台物理机的情况，需要存储276T的数据，平均下来差不多一台56T的数据。这个具体看磁盘数和盘的大小1.3.2 SAS还是SSD现在我们需要考虑一个问题：是需要SSD固态硬盘，还是普通机械硬盘？SSD就是固态硬盘，比机械硬盘要快，那么到底是快在哪里呢？其实SSD的快主要是快在磁盘随机读写，就要对磁盘上的随机位置来读写的时候，SSD比机械硬盘要快。比如说MySQL这种就应该使用SSD了（MySQL需要随机读写）。比如说我们在规划和部署线上系统的MySQL集群的时候，一般来说必须用SSD，性能可以提高很多，这样MySQL可以承载的并发请求量也会高很多，而且SQL语句执行的性能也会提高很多。因为写磁盘的时候kafka是顺序写的。机械硬盘顺序写的性能机会跟内存读写的性能是差不多的，所以对于Kafka集群来说其实使用机械硬盘就可以了。如果是需要自己创业或者是在公司成本不足的情况下，经费是能够缩减就尽量缩减的。1.4 内存角度JVM非常怕出现full gc的情况。kafka自身的jvm是用不了过多堆内存的，因为kafka设计就是规避掉用jvm对象来保存数据，避免频繁full gc导致的问题，所以一般kafka自身的jvm堆内存，分配个10G左右就够了，剩下的内存全部留给os cache。那服务器需要多少内存呢。我们估算一下，大概有100个topic，所以要保证有100个topic的leader partition的数据在操作系统的内存里。100个topic，一个topic有5个partition。那么总共会有500个partition。每个partition的大小是1G（在上一篇中的日志分段存储中规定了.log文件不能超过1个G），我们有2个副本，也就是说要把100个topic的leader partition数据都驻留在内存里需要1000G的内存。我们现在有5台服务器，所以平均下来每天服务器需要200G的内存，但是其实partition的数据我们没必要所有的都要驻留在内存里面，只需要25%的数据在内存就行，200G * 0.25 = 50G就可以了（因为在集群中的生产者和消费者几乎也算是实时的，基本不会出现消息积压太多的情况）。所以一共需要60G（附带上刚刚的10G Kafka服务）的内存，故我们可以挑选64G内存的服务器也行，大不了partition的数据再少一点在内存，当然如果能够提供128G内存那就更好。1.5 CPU coreCPU规划，主要是看你的这个进程里会有多少个线程，线程主要是依托多核CPU来执行的，如果你的线程特别多，但是CPU核很少，就会导致你的CPU负载很高，会导致整体工作线程执行的效率不太高，上一篇的Kafka的网络设计中讲过Kafka的Broker的模型。acceptor线程负责去接入客户端的连接请求，但是他接入了之后其实就会把连接分配给多个processor，默认是3个，但是一般生产环境建议大家还是多加几个，整体…

RAID5 真的安全吗
type: item
date: 2020-03-02T14:01:00+00:00
description: 转载自知乎一句话结论：现代大容量硬盘组成的RAID 5单盘故障后，重建失败的概率相当高，不可忽略；但数据本身还是基本安全的（会丢失部分文件），只是可能需要一个比较麻烦的恢复方案。楼上包括高赞回答在内一堆说两个硬盘同时坏的，要加一个热备盘的，都是没仔细看过问题里面的链接就回答的。在回答问题的现在，这个链接失效了，但网上还是有人转载过的，例如这篇[1]：DBA亲，你们的RAID5阵列有保障吗？marbury关注0人评论10546人阅读2014-02-21 10:30:24 该文章主要整理论坛内容。（论坛地址：http://bbs.et8.net/bbs/showthread.php?t=1026112）很多人遇到过服务器RAID5挂掉，往往掉一个盘后，第二个盘也立刻挂掉。引用：RAID 5也是以数据的校验位来保证数据的安全，但它不是以单独硬盘来存放数据的校验位，而是将数据段的校验位交互存放于各个硬盘上。这样，任何一个硬盘损坏，都可以根据其它硬盘上的校验位来重建损坏的数据。硬盘的利用率为n-1。如果挂掉两个盘，数据就玩完了。 理论上两个硬盘同时失效的概率是很低的，但为什么会这样呢？ 引用：从数学角度说，每个磁盘的平均无故障时间 (MTBF) 大约为 50 万至 150 万小时(也就是每 50～150 年发生一次硬盘损坏)。实际往往不能达到这种理想的情况，在大多数散热和机械条件下，都会造成硬盘正常工作的时间大幅减少。考虑到每个磁盘的寿命不同，阵列中的任何磁盘都可能出现问题，从统计学角度说，阵列中 N 个磁盘发生故障的机率比单个磁盘发生故障的机率要大 N 倍。结合上述因素，如果阵列中的磁盘数量合理，且这些磁盘的平均无故障时间 (MTBF) 较短，那么在磁盘阵列的预期使用寿命过程中，就很有可能发生磁盘故障(比方说每几个月或每隔几年就会发生一次故障)。 两块磁盘同时损坏的几率有多大呢(“同时”就是指一块磁盘尚未完全修复时另一块磁盘也坏掉了)?如果说 RAID 5 阵列的MTBF相当于MTBF^2，那么这种几率为每隔10^15个小时发生一次(也就是1万多年才出现一次)，因此不管工作条件如何，发生这种情况的概率是极低的。从数学理论角度来说，是有这种概率，但在现实情况中我们并不用考虑这一问题。不过有时却是会发生两块磁盘同时损坏的情况，我们不能完全忽略这种可能性，实际两块磁盘同时损坏的原因与MTBF基本没有任何关系。 对这种情况来说，这里首先要引入一个一般人不常接触到的概念：BER 硬盘误码率,英文是BER(Bit Error Rate),是描述硬盘性能的一个非常重要的参数,是衡量硬盘出错可靠性的一个参数。这个参数代表你写入硬盘的数据，在读取时遇到不可修复的读错误的概率。从统计角度来说也比较少见，一般来说是指读取多少位后会出现一次读取错误。 随着硬盘容量增加，驱动器读取数据的误读率就会增加，而硬盘容量暴涨，误码率的比例一直保持相对增加。一个1TB的驱动器是需要更多读取整个驱动器，这是在RAID重建期间发生错误的概率会比300G 驱动器遇到错误的几率大。 那这个错误的几率到底有多大呢？或者说，我们写入多少GB数据，才会遇到1byte的读取错误呢？看这篇文章：http://lenciel.cn/docs/scsi-sata-reliability/对于不同类型的硬盘（以前企业级、服务器、数据中心级硬盘用SCSI/光纤，商用、民用级别是IDE；现在对应的则是SAS/SATA； 他们的MRBF（平均无故障时间）是接近的，但是BER便宜的SATA硬盘要比昂贵的SCSI硬盘的误码率（BER）要高得多。 也就是说，出现某个sector无法读取的情况，SATA要比SCSI严重得多。具体区别在固件上：遇到读取不过去，或者写入不过去的坏道时，家用硬盘会花费1分钟以上的时间去尝试纠正错误，纠正不了就直接用备用扇区代替，这个时间超过阵列控制器能容忍的限度，所以遇到这种情况直接掉盘；企业级的磁盘会把这项工作放在后台进行，不需要停顿1分钟左右的时间，从而不影响阵列运行。在BER 硬盘误码率上没有任何区别。 按照文中的计算，一个1TB的硬盘，通常你无法读取所有sector的概率达到了56%，因此你用便宜的大容量SATA盘，在出现硬盘故障的情况下重建RAID的希望是：无法实现。 用1TB的SATA硬盘做RAID5的话，当你遇到一个硬盘失效的情况，几乎剩下的两个以上硬盘（RAID5最少组合是3个）铁定会遇到一个硬盘读取错误，从而重建失败。 所以，以前小硬盘做RAID5，基本很少遇到同时挂掉两个盘的情况；现在硬盘大了，出问题的概率也越来越大了。 对于跑RAID的用户，对整个硬盘进行读取的事情经常发生。即使系统足够和谐，知道不对你报告那些出现在你从不读取的文件中的坏道，但是也只是略过了…

Cache 和 Buffer 有什么区别？
type: item
date: 2019-12-19T07:57:38+00:00
description: Cache和Buffer是两个不同的概念，简单的说，Cache是加速“读”，而buffer是缓冲“写”，前者解决读的问题，保存从磁盘上读出的数据，后者是解决写的问题，保存即将要写入到磁盘上的数据。在很多情况下，这两个名词并没有严格区分，常常把读写混合类型称为buffer cache，本文后续的论述中，统一称为cache。Oracle中的log buffer是解决redo写入的问题，而data buffer cache则解决data block的读写问题。对于Oracle来说，如果IO没有在SGA中命中，都会发生物理IO，Oracle并不关心底层存储的类型，可能是一套存储系统，可能是本地磁盘，可能是RAID 10，也可能是RAID 5，可能是文件系统，也可能是裸设备，或是ASM。总之，Oracle把底层的存储系统称为存储子系统。在存储系统中，cache几乎无处不在（在后面的论述中，我们统称为cache），文件系统有cache，存储有cache，RAID控制器上有cache，磁盘上也有cache。为了提高性能，Oracle的一个写操作，很有可能写在存储的cache上就返回了，如果这时存储系统发生问题，Oracle如何来保证数据一致性的问题。Oracle数据库最重要的特性是：Write ahead logging，在data block在写入前，必须保证首先写入redo log，在事务commit时，同时必须保证redo log被写入。Oracle为了保证数据的一致性，对于redo log采用了direct IO，Direct IO会跳过了OS上文件系统的cache这一层。但是，OS管不了存储这一层，虽然跳过了文件系统的cache，但是依然可能写在存储的cache上。一般的存储都有cache，为了提高性能，写操作在cache上完成就返回给OS了，我们称这种写操作为write back，为了保证掉电时cache中的内容不会丢失，存储都有电池保护，这些电池可以供存储在掉电后工作一定时间，保证cache中的数据被刷入磁盘，不会丢失。不同于UPS，电池能够支撑的时间很短，一般都在30分钟以内，只要保证cache中的数据被写入就可以了。存储可以关闭写cache，这时所有的写操作必须写入到磁盘才返回，我们称这种写操作为write throuogh，当存储发现某些部件不正常时，存储会自动关闭写cache，这时写性能会下降。RAID卡上也有cache，一般是256M，同样是通过电池来保护的，不同于存储的是，这个电池并不保证数据可以被写入到磁盘上，而是为cache供电以保护数据不丢失，一般可以支撑几天的时间。还有些RAID卡上有flash cache，掉电后可以将cache中的内容写入到flash cache中，保证数据不丢失。如果你的数据库没有存储，而是放在普通PC机的本地硬盘之上的，一定要确认主机中的RAID卡是否有电池，很多硬件提供商默认是不配置电池的。当然，RAID卡上的cache同样可以选择关闭。磁盘上的cache，一般是16M-64M，很多存储厂商都明确表示，存储中磁盘的cache是禁用的，这也是可以理解的，为了保证数据可靠性，而存储本身又提供了非常大的cache，相比较而言，磁盘上的cache就不再那么重要。SCSI指令中有一个FUA(Force Unit Access)的参数，设置这个参数时，写操作必须在磁盘上完成才可以返回，相当于禁用了磁盘的写cache。虽然没有查证到资料，但是我个人认为一旦磁盘被接入到RAID控制器中，写cache就会被禁用，这也是为了数据可靠性的考虑，我相信存储厂商应该会考虑这个问题。至此，我们可以看到Oracle的一个物理IO是经历了一系列的cache之后，最终被写入到磁盘上。cache虽然可以提高性能，但是也要考虑掉电保护的问题。关于数据的一致性，是由Oracle数据库，操作系统和存储子系统共同来保证的。

vmware不重启扩展磁盘
type: item
date: 2019-10-03T11:52:05+00:00
description: 在vmware环境下，有时出现虚拟机磁盘不够用的情况，需要给原有硬盘扩容或者新增硬盘，但一般情况下下，Linux扩容硬盘或者新增硬盘都需要重启系统后才能识别，下面主要讲如何在不重启系统的情况下，如何实现硬盘空间的扩容（前提是系统使用LVM）。vmware操作首先，在esxi（或者workstation）中选择虚拟机设置，选中硬盘，直接调整大小（只能增加，不能减少），或者添加一块新的硬盘。磁盘扩容后系统操作完成虚拟机硬盘扩容后，登录到系统中，执行fdisk -l命令，发现硬盘空间并未增加，如图：此时，需要重新扫描存储设备的SCSI总线，有两种方式：方法1 .echo 1 > /sys/class/scsi_disk/2\:0\:0\:0/device/rescan如下图，其中红框部分需要根据实际的路径进行替换重新执行fdisk，发现磁盘容量已经增加。方法 2 .echo 1 > /sys/block/$DISK/device/rescan其中，$DISK用需要重新扫描的磁盘代替，如sda、sdb等添加磁盘后系统操作[root@localhost ~]# grep mpt /sys/class/scsi_host/host?/proc_name /sys/class/scsi_host/host2/proc_name:mptspi [root@localhost ~]# echo "- - -" > /sys/class/scsi_host/host2/scan其中，host2使用第一步中获取的名称替换。扫描SCSI总线后对LVM的操作系统能识别到磁盘之后，接下来要做的就是扩容LVM了，分为以下几种情况；非系统磁盘扩容，使用pvresize对pv进行扩容，之后按照正常lv扩容流程进行扩容即可。pvresize /dev/sdb lvextend -l +100%FREE <lvname>添加磁盘，扩容lvm，使用pvcreate将新加的磁盘创建为新的pv，将pv加入到vg，然后扩容lv即可。扩容完成lv之后，需要对文件系统重新定义大小，执行resize2fs 设备文件名即可另外，系统盘扩容后，暂时没找到不重启扩容的方法，如有哪位朋友有好的方法，欢迎提出常见问题：创建pv的时候报错：Device /dev/sdb1 not found (or ignored by filtering).执行partprobe命令，使kernel重新读取分区信息即可