精华内容
下载资源
问答
  • 2019-08-05 16:42:30

    在传统观念里, 单片机WIFI通信,尤其是单片机高速WIFI通信传输,是一个不现实的梦想,原因一般在于:
    (1) 能做高速通信的WIFI模块,一般只是USB、SDIO、或PCIE之类的接口,而大多数普通单片机都不会提供这些主机接口;
    (2)即使某些款的单片机也能提供这些接口,也会单片机和WIFI模块的通信编程变得非常复杂,同时也会造成单片机选型的成本增加;
    (3)普通单片机因为资源(性能和存储)有限,也难以支持实用的较好性能的单片机WIFI方案。

    所以,大多数用在单片机系统上的WIFI模块,要么是以串口为主的,只能做一些基本的低速控制命令的传输,或者费了九牛二虎之力,集成了USB、 SDIO、或PCIE接口的WIFI模块,其做出来的效果也很一般,速度一般也不超过300K字节每秒。因此,在普通单片机做高速WIFI通信,基本上成为了一个不可实现的梦想,并甚至成为一种传统惯性认识。

    ALK8266WIFI, 基于SPI接口的高速WIFI模块,在多款普通单片机上,包括STM32系列及其兼容系列(如国产GD系列)、NXP系列(LPC和iMX跨接处理器)、TI DSP(如TMS320F28335)、Nuvoton新塘系列、C8051系列 ,以及一些国产单片机等多款常见的主流单片机主机,测试验证,实现了高速传输,普通环境下,实测有效速度可以超过兆字节每秒,长时间运行不掉线、不丢包,在单片机音视频传输、高速采集数据传输场合都得到了超过了一年以上的产品化的验证。而且集成简单(就象访问普通的SPI外设一样简单),占用单片机资源少(无需在单片机上集成操作系统或协议栈)。该方案功能强大、性能高、稳定,集成移植简单、适应面广,精致小巧。性价比超高。

    点击此链接可以查看测速演示视频https://v.douyin.com/Ftj8vMD/

    在某宝搜索 “SPI 高速 多链接”  里面有更进一步的详细介绍,很技术化。

    ALK8266高速WIFI模组 SPI接口 带WEB网页 音视频传输产品化验证

    在某宝搜索 “SPI 高速 多链接”  里面有更进一步的详细介绍,很技术化

    1. 有效通信速度快,效率高,通信实时性好
       1.1 “实测的”“有效”吞吐速度高,超过M字节每秒(MBytes/s),所以可用来传输音视频或大量数据
       1.2 准实时性收发,连续发包之间的间隔可在ms级或us级,可适应一些对传输性实时性有要求的场合。
    2. 稳定可靠不丢包,长时间通信不掉线
       2.1 测试条件:普通办公室环境实测
       2.2 测试速度:速度稳定在兆字节每秒(MBytes/s)以上
       2.3 长时间运行测试:持续运行30天,不掉线、传输不停止/不卡死
       2.4 丢包测试:TCP通信持续测试过5小时以上,不丢包、不多包,不丢字节、不多多字节,收发方数据完全一样。
           测试场景包括:(1)TCPUDP抓包软件单纯发送, 模块单纯接收
                                   (2)TCPUDP抓包软件单纯接收, 模块单纯发送
                                   (3)TCPUDP抓包软件同时发收, 模块同时收发
                                   (4)两个WIFI模块之间互相对发对收
    3. 功能全面,使用灵活,使用场合适应面广
       3.1 灵活实用的无线通信
           3.1.1 模块支持 工作站STA, 热点AP 以及 STA+AP 混合模式,无论是否存在第三方热点,都可实现通信
           3.1.2 支持UDP,TCP客户端,TCP服务器,灵活方便
           3.1.3 UDP通信支持广播、组播以及单播,灵活高效
           3.1.4 支持多链接,每个链接独立随意配置,实用的多通道高速通信
           3.1.5 支持多客户端,模组作为TCP服务器可以同时和多个客户端通信
           3.1.6 支持大块数据阵发发送,适合一些文件等大块数据传输需求的场合
       3.2 内嵌WEB服务器,操作更灵活和便捷
           3.2.1 无需安装APP,直接通过常见的浏览器操作
           3.2.2 普通智能手机或电脑均可直接操作
           3.2.3 支持“自动弹出网页”功能
           3.2.4 可通过网页直接配网、配置热点、建立和查询链接通道信息等操作
       3.3 配网方式灵活多样方便
           3.3.1 WEB网页配网:勿需安装APP,直接输入,简单方便,受限条件少
           3.3.2 智能配网:SmartConfig/SmartLink, 微信Airkiss扫一扫;
                 -特色 提供配网进展灯闪烁样式,提高智能配网操作方便性。
           3.3.3 直接配网:串口AT指令、SPI接口API函数 直接输入
       3.4 内嵌RSA加密和签名算法
           3.4.1 可作为加密芯片使用,支持单片机固件的防复制
       3.5 支持有意义的低功耗
           3.5.1 确保有用发射功耗足够强传输距离足够远的前提下的低功耗机制
           3.5.2 支持休眠,自动唤醒或手动唤醒
           3.5.3 深度休眠电流低于1mA
     4. 封装灵活、尺寸小巧
     
     4.1 整孔和半孔(邮票孔)一体化设计
       4.2 兼容插件方式或贴片装配方式
       4.3 大小和一枚1角硬币相当
    5. 常见通用的SPI单片机主机接口,集成简单,占用单片机资源少
     
     5.1 主机接口为标准的SPI从,适配绝大多数的常见单片机,单片机选型范围广
           - 硬件接线简单,只需要标准的SPI总线管脚,无需额外的UART串口
           - 按照普通的SPI从机方式对模块进行读写,实现单片机与模块的配置查询以及传输通信
       5.2 模块上已集成了TCPIP协议栈,
           - 单片机无需再集成相关协议栈或操作系统,
           - 因此集成简单,占用单片机资源少,且通信效率也更高
    6. 提供单片机例程包、集成说明等资料文档,和技术支持
       6.1 单片机例程包都经过实际测试和验证
       6.2 集成说明文档和开发使用技巧,都是基于开发经验和客户反馈总结编写,非简单的协议复制
       6.3 可提供目前市场上主流的单片机例程包,包括但不限于:
           - STM32系列(如F1/F2/F3/F4/F7 H7 L1/L4)
           - NXP LPC17xx系列
           - NXP K60, K27/28系列、
           - NXP i.MX RT10xx系列、
           - C8051系列、
           - Nuvoton新塘 NUC123xx系列、M45x系列、
           - TI MSP430系列
           - TI C2000/C5000(如TMS320F28335)
           - 等
    在某宝搜索 “SPI 高速 多链接”  排名靠前的就是,里面有更进一步的详细介绍,很技术化。

    更多相关内容
  • 我一直很喜欢 Cassandra 的基准测试,它显示它在EC2和Google Compute Engine上的三百台机器上每秒执行一百万次写入。我不知道为什么,也许这是邪恶博士的事情,但每秒做一百万件事情很有趣。 无论如何,Kafka 日志...

    原文地址

    翻译:sealos 是以kubernetes为内核的云操作系统发行版,3min 一键高可用安装自定义kubernetes,500M,100年证书,版本不要太全,生产环境稳如老狗。

    我写了一篇关于 LinkedIn 如何使用Apache Kafka作为中央发布-订阅日志的博客文章,用于在应用程序、流处理和 Hadoop 数据摄取之间集成数据。

    file

    但是,要真正完成这项工作,这个“通用日志”必须是一种廉价的抽象。如果您想将系统用作中央数据中心,它必须快速、可预测且易于扩展,以便您可以将所有数据转储到该系统上。我的经验是,脆弱或昂贵的系统不可避免地会形成一道保护过程墙,以防止人们使用它们;易于扩展的系统通常最终成为关键的架构构建块,因为使用它是构建事物的最简单方法。

    我一直很喜欢 Cassandra 的基准测试,它显示它在EC2和Google Compute Engine上的三百台机器上每秒执行一百万次写入。我不知道为什么,也许这是邪恶博士的事情,但每秒做一百万件事情很有趣。

    无论如何,Kafka 日志的优点之一是,正如我们将看到的,它很便宜。每秒一百万次写入并不是什么特别大的事情。这是因为日志比数据库或键值存储要简单得多。事实上,我们的生产集群全天每秒进行数千万次读取和写入,而且它们是在相当普通的硬件上完成的。

    但是让我们做一些基准测试并看看。

    卡夫卡30秒

    为了帮助理解基准,让我快速回顾一下 Kafka 是什么以及它如何工作的一些细节。Kafka 是一个分布式消息系统,最初是在 LinkedIn 构建的,现在是Apache 软件基金会的一部分,并被各种公司使用。

    一般设置非常简单。生产者将记录发送到保存这些记录并将它们分发给消费者的集群:

    file

    Kafka 的关键抽象是主题。生产者将他们的记录发布到一个主题,消费者订阅一个或多个主题。Kafka 主题只是一个分片的预写日志。生产者将记录附加到这些日志中,消费者订阅更改。每条记录都是一个键/值对。密钥用于将记录分配给日志分区(除非发布者直接指定分区)。

    这是一个简单的例子,一个生产者和消费者从两个分区的主题中读写。

    file

    这张图片显示了一个附加到两个分区的日志的生产者进程,以及一个从相同日志中读取的消费者。日志中的每条记录都有一个关联的条目号,我们称之为偏移量。消费者使用这个偏移量来描述它在每个日志中的位置。

    这些分区分布在一组机器上,允许一个主题保存比任何一台机器都多的数据。

    请注意,与大多数消息传递系统不同,日志始终是持久的。收到消息后会立即将其写入文件系统。消息在阅读时不会被删除,但会保留一些可配置的 SLA(比如几天或一周)。这允许在数据使用者可能需要重新加载数据的情况下使用。它还可以支持节省空间的发布-订阅,因为无论有多少消费者,都有一个共享日志;在传统的消息传递系统中,每个消费者通常都有一个队列,因此添加消费者会使数据大小翻倍。这使得 Kafka 非常适合常规消息传递系统范围之外的事物,例如充当 Hadoop 等离线数据系统的管道。这些离线系统可能仅作为周期性 ETL 周期的一部分每隔一段时间加载,

    Kafka 还将其日志复制到多个服务器上以实现容错。与其他消息传递系统相比,我们的复制实现的一个重要架构方面是复制不是需要复杂配置的外来附加组件,仅用于非常特殊的情况。相反,复制被假定为默认值:我们将未复制的数据视为复制因子恰好为 1 的特殊情况。

    生产者在发布包含记录偏移量的消息时会收到确认。发布到分区的第一条记录的偏移量为 0,第二条记录的偏移量为 1,依此类推,以不断增加的顺序。消费者从偏移指定的位置消费数据,并通过定期提交将其位置保存在日志中:保存此偏移以防消费者实例崩溃并且另一个实例需要从其位置恢复。

    好的,希望这一切都有意义(如果没有,您可以在此处阅读更完整的 Kafka 介绍)。

    本基准

    这个测试是针对主干的,因为我对这个基准的性能测试做了一些改进。但是自上次完整版本以来并没有太大变化,因此您应该会看到与0.8.1类似的结果。我还在使用我们新重写的Java producer,它比以前的 producer 客户端提供了更大的吞吐量。

    我遵循了这个非常好的RabbitMQ 基准测试的基本模板,但我涵盖了与 Kafka 更相关的场景和选项。

    关于这个基准的一个快速的哲学注释。对于将要公开报告的基准,我喜欢遵循一种我称之为“惰性基准”的风格。当您在一个系统上工作时,您通常具有针对任何特定用例将其调整到完美的专业知识。这会导致一种基准测试,在这种测试中,您需要根据基准对配置进行大量调整,或者更糟的是,对您测试的每个场景进行不同的调整。我认为一个系统的真正测试不是它在完美调整时的表现,而是它如何“现成”地表现。对于在具有数十个或数百个用例的多租户设置中运行的系统尤其如此,其中为每个用例进行调整不仅不切实际而且不可能。结果,我几乎坚持使用服务器和客户端的默认设置。

    我已经发布了我的确切配置和命令,因此如果您有兴趣,应该可以在您自己的设备上复制结果。

    硬件设置

    对于这些测试,我有六台机器,每台都有以下规格

    六核 Intel Xeon 2.5 GHz 处理器 六个 7200 RPM SATA 驱动器 32GB 内存 1Gb 以太网 Kafka 集群设置在三台机器上。六个驱动器直接安装,没有 RAID(JBOD 样式)。其余三台机器我用于 Zookeeper 和生成负载。

    三机集群不是很大,但由于我们只测试最多三倍的复制因子,这就是我们所需要的。应该很明显,我们总是可以添加更多的分区并将数据分布到更多的机器上以水平扩展我们的集群。

    这个硬件实际上并不是 LinkedIn 的普通 Kafka 硬件。我们的 Kafka 机器更接近于运行 Kafka,但不太符合我在这些测试中所追求的“现成”精神。相反,我从我们的一个 Hadoop 集群中借用了这些,它运行在我们所有持久系统中可能是最便宜的设备上。Hadoop 使用模式与 Kafka 非常相似,因此这是合理的做法。

    好了,废话不多说,结果!

    生产者吞吐量

    这些测试将强调生产者的吞吐量。在这些测试期间没有运行消费者,因此所有消息都被持久化但不被读取(稍后我们将测试生产者和消费者的案例)。由于我们最近重写了我们的生产者,我正在测试这个新代码。

    单生产者线程,无复制

    821,557 条记录/秒 (78.3 MB/秒) 对于第一个测试,我创建了一个包含六个分区且没有复制的主题。然后我尽可能快地从单个线程中生成 5000 万条小(100 字节)记录。

    在这些测试中关注小记录的原因是,对于消息传递系统来说(通常)更难。如果消息很大,很容易获得以 MB/sec 为单位的良好吞吐量,但当消息较小时,要获得良好的吞吐量则要困难得多,因为处理每条消息的开销占主导地位。

    在整个基准测试中,当我报告 MB/秒时,我只报告每秒请求的记录值大小,不包括请求的其他开销。所以实际的网络使用率比报告的要高。例如,对于一个 100 字节的消息,我们还将为每条消息传输大约 22 个字节的开销(用于可选密钥、大小分隔、消息 CRC、记录偏移量和属性标志),以及请求的一些开销(包括主题、分区、所需的确认等)。这使得我们更难看出我们在哪里达到了 NIC 的限制,但这似乎比在吞吐量数字中包括我们自己的开销字节更合理一些。因此,在上述结果中,我们很可能使客户端机器上的 1 Gb NIC 饱和。

    一个直接的观察结果是这里的原始数据比人们预期的要高得多,尤其是对于持久存储系统。如果您习惯于随机访问数据系统,例如数据库或键值存储,您通常会期望最大吞吐量约为每秒 5,000 到 50,000 个查询,因为这接近于一个好的 RPC 层可以做到的速度远程请求。由于两个关键设计原则,我们超越了这一点:

    我们努力确保我们进行线性磁盘 I/O。这些服务器的六个廉价磁盘提供了 822 MB/秒的线性磁盘 I/O 总吞吐量。这实际上远远超出了我们仅使用 1 Gb 网卡所能使用的能力。许多消息传递系统将持久性视为会降低性能的昂贵附加组件,因此应谨慎使用,但这是因为它们无法进行线性 I/O。 在每个阶段,我们都致力于将少量数据批处理到更大的网络和磁盘 I/O 操作中。例如,在新的生产者中,我们使用类似“组提交”的机制来确保在另一个 I/O 正在进行时发起的任何记录发送都被组合在一起。有关了解批处理重要性的更多信息,请查看 David Patterson 关于为什么“延迟滞后带宽”的演示文稿。 如果您对细节感兴趣,您可以在我们的设计文档中阅读更多相关信息。

    单生产者线程,3x 异步复制

    786,980 条记录/秒 (75.1 MB/秒) 这次测试和上一次完全一样,只是现在每个分区都有三个副本(因此写入网络或磁盘的总数据是三倍)。每个服务器都在从生产者对它作为主的分区执行写入操作,以及为它作为从属的分区获取和写入数据。

    此测试中的复制是异步的。也就是说,服务器在将写入写入其本地日志后立即确认写入,而无需等待其他副本也确认它。这意味着,如果主服务器崩溃,它可能会丢失最后几条已写入但尚未复制的消息。这使得消息确认延迟稍微好一点,但在服务器故障的情况下会带来一些风险。

    我希望人们从中获得的关键是复制可以很快。集群的总写入容量当然要少 3 倍,复制 3 倍(因为每次写入完成 3 次),但每个客户端的吞吐量仍然相当不错。高性能复制很大程度上来自我们消费者的效率(副本实际上只不过是一个专门的消费者),我将在消费者部分讨论。

    单生产者线程,3x 同步复制

    421,823 条记录/秒 (40.2 MB/秒) 此测试与上面相同,只是现在分区的主服务器在向生产者确认之前等待来自完整同步副本集的确认。在这种模式下,我们保证只要保留一个同步副本,消息就不会丢失。

    Kafka 中的同步复制与异步复制没有本质上的区别。分区的领导者总是跟踪跟随者副本的进度以监控它们的活跃性,并且我们永远不会向消费者发出消息,直到它们被副本完全确认。使用同步复制,我们只需等待响应生产者请求,直到追随者复制它。

    这种额外的延迟似乎确实会影响我们的吞吐量。由于服务器上的代码路径非常相似,我们可以通过将批处理调整为更积极一些并允许客户端缓冲更多未完成的请求来改善这种影响。但是,本着避免特殊情况调整的精神,我避免了这种情况。

    三个生产者,3x 异步复制

    2,024,032 条记录/秒 (193.0 MB/秒) 我们的单一生产者进程显然没有对我们的三节点集群造成压力。为了增加一点负载,我现在将重复之前的异步复制测试,但现在使用在三台不同机器上运行的三个生产者负载生成器(在同一台机器上运行更多进程无济于事,因为我们正在使 NIC 饱和)。然后我们可以查看这三个生产者的总吞吐量,以更好地了解集群的总容量。

    生产者吞吐量与存储数据

    许多消息传递系统的隐藏危险之一是,只要它们保留的数据适合内存,它们就可以正常工作。当数据备份并且没有被消耗(因此需要存储在磁盘上)时,它们的吞吐量会下降一个数量级(或更多)。这意味着只要您的消费者跟上并且队列是空的,事情就可能运行良好,但是一旦它们滞后,整个消息传递层就会备份未使用的数据。备份导致数据进入磁盘,进而导致性能下降到一个速率,这意味着消息传递系统无法再跟上传入的数据,要么备份要么崩溃。这非常糟糕,因为在许多情况下,队列的全部目的是优雅地处理这种情况。

    由于 Kafka 总是持久化消息,因此相对于未消耗的数据量,性能是 O(1)。

    为了进行实验测试,让我们在较长时间内运行吞吐量测试,并随着存储数据集的增长绘制结果:

    file

    该图确实显示了性能上的一些差异,但由于数据大小没有影响:我们在写入 TB 数据后的性能与前几百 MB 的性能一样好。

    这种差异似乎是由于 Linux 的 I/O 管理设施对数据进行批处理,然后定期刷新。这是我们在我们的生产 Kafka 设置中调整的更好一点。此处提供了有关调整 I/O 的一些说明。

    消费者吞吐量

    好的,现在让我们将注意力转向消费者吞吐量。

    请注意,复制因子不会影响此测试的结果,因为无论复制因子如何,消费者都只会从一个副本中读取。同样,生产者的确认级别也无关紧要,因为消费者只读取完全确认的消息(即使生产者不等待完全确认)。这是为了确保消费者看到的任何消息在领导交接后始终存在(如果当前领导失败)。

    单一消费者

    940,521 条记录/秒 (89.7 MB/秒) 对于第一个测试,我们将在单个线程中从 6 个分区 3x 复制主题中消耗 5000 万条消息。

    Kafka 的消费者非常高效。它通过直接从文件系统获取日志块来工作。它使用sendfile API直接通过操作系统传输此数据,而无需通过应用程序复制此数据的开销。这个测试实际上是从日志的开头开始的,所以它是在做真正的读 I/O。但是,在生产环境中,消费者几乎完全从操作系统页面缓存中读取,因为它正在读取刚刚由某个生产者写入的数据(因此它仍然被缓存)。事实上,如果您在生产服务器上运行 I/O stat,您实际上会看到根本没有物理读取,即使正在消耗大量数据。

    让消费者便宜对于我们希望 Kafka 做的事情很重要。一方面,复制品本身就是消费者,因此让消费者便宜会使复制品便宜。此外,这使得处理数据成为一种成本低廉的操作,因此出于可扩展性的原因,我们不需要严格控制。

    三个消费者

    2,615,968 条记录/秒 (249.5 MB/秒) 让我们重复相同的测试,但运行三个并行的消费者进程,每个进程都在不同的机器上,并且都使用相同的主题。

    正如预期的那样,我们看到了接近线性的缩放(这并不奇怪,因为我们模型中的消耗非常简单)。

    生产者和消费者

    795,064 条记录/秒 (75.8 MB/秒) 上述测试仅涵盖了单独运行的生产者和消费者。现在让我们做自然的事情并将它们一起运行。实际上,我们在技术上已经这样做了,因为我们的复制是通过让服务器本身充当消费者来工作的。

    都一样,让我们​​运行测试。对于这个测试,我们将在开始为空的六个分区 3x 复制主题上运行一个生产者和一个消费者。生产者再次使用异步复制。报告的吞吐量是消费者吞吐量(显然,这是生产者吞吐量的上限)。

    正如我们所预料的那样,我们得到的结果与我们在仅生产者的情况下看到的基本相同——消费者相当便宜。

    消息大小的影响

    我主要展示了小 100 字节消息的性能。较小的消息对于消息传递系统来说是更难的问题,因为它们会放大系统记账的开销。当我们改变记录大小时,我们可以通过以记录/秒和 MB/秒为单位绘制吞吐量来显示这一点。

    file

    因此,正如我们所料,这张图显示我们每秒可以发送的原始记录数随着记录变大而减少。但是,如果我们查看 MB/秒,我们会看到真实用户数据的总字节吞吐量随着消息变大而增加:

    file

    我们可以看到,对于 10 字节的消息,我们实际上是 CPU 绑定的,仅通过获取锁并将消息排入队列以进行发送——我们实际上无法最大化网络。然而,从 100 字节开始,我们实际上看到了网络饱和(尽管 MB/sec 继续增加,因为我们的固定大小的簿记字节在发送的总字节中所占的百分比越来越小)。

    端到端延迟 2 毫秒(中位数) 3 毫秒(第 99 个百分位) 14 毫秒(第 99.9 个百分位) 我们已经谈了很多关于吞吐量的问题,但是消息传递的延迟是多少?也就是说,我们发送的消息需要多长时间才能传递给消费者?对于这个测试,我们将创建生产者和消费者,并重复计算生产者向 kafka 集群发送消息然后被消费者接收所需的时间。

    请注意,Kafka 仅在完全同步的副本集确认消息时才向消费者发送消息。因此,无论我们使用同步复制还是异步复制,此测试都会给出相同的结果,因为该设置仅影响对生产者的确认。

    复制此测试 如果您想在自己的机器上尝试这些基准测试,您可以。正如我所说,我大多只是使用 Kafka 附带的预打包性能测试工具,并且大多坚持使用服务器和客户端的默认配置。但是,您可以在此处查看配置和命令的更多详细信息。 sealos 以kubernetes为内核的云操作系统发行版,让云原生简单普及

    laf 写代码像写博客一样简单,什么docker kubernetes统统不关心,我只关心写业务!

    展开全文
  • 背景作为一家大规模的自营式电商企业,京东需要存储海量的非结构化数据:商品图片、订单文本、仓库流转记录、App客户端文件、日志文件、内部文档等。对于存储这些数据,之前并没有统一的解决方案,都是各个业务线...

    背景

    作为一家大规模的自营式电商企业,京东需要存储海量的非结构化数据:商品图片、订单文本、仓库流转记录、App客户端文件、日志文件、内部文档等。对于存储这些数据,之前并没有统一的解决方案,都是各个业务线自行解决——MySQL BLOB、HDFS、FastDFS。

    2013年5月,京东开始组建存储组,自主研发JFS——京东文件系统,以实现非结构化数据存储统一服务为目标。

    小文件存储

    针对3个典型的应用场景——商品图片、OFC订单、WMS库房流水,JFS第一版定位为海量小文件存储,其核心功能定义如下。

    • 海量小文件存储,极高的可靠性、可用性与一致性。
    • Key-File数据模型,Key由系统生成,全局唯一;文件immutable,即不可修改,甚至极少被删除。

    其主要包含如下3个模块。

    • ZooKeeper作为集群协调器管理元数据信息。
    • 由Go语言开发的DataNode,实现服务端读写逻辑、复制协议、故障恢复等。每个DataNode管理一块磁盘——该设计大幅简化了工程实现。
    • 由Java开发的客户端。

    复制协议实现了一种Paxos变体,或者说一种极简的Paxos实现,如图1所示:固定成员(一个复制组由1primary + 2follower构成)、固定角色(primary与follower角色不会发生变更)、固定读写流程(client将写操作发送到primary,它在写本地的同时将写操作发给两个follower,三副本都写入成功后才成功返回给用户;优先在follower上读取,提高系统的并发能力)。

    存储引擎采用Append-Only方式,每个DataNode维护一组(默认配置为512)Chunk大文件,客户端上传的小文件(如一张图片)被并行追加至一个复制组三名成员对应的Chunk中,如图2所示。

    这里写图片描述

    图1 JFS小文件复制协议

    这里写图片描述

    图2 JFS小文件数据存储

    JFS为每个成功上传的小文件生成全局唯一的JFS Key来编码其存储位置信息:

    JFS Key = Replica Group ID/Chunk ID/Offset/Length/Checksum/Signature

    比如,jfs/t3442/251/2127752103/150148/57583d02/5844d73fNaca4af3d.jpg是京东网站上一款电饭煲的主图的JFS Key,表示该图片存储在3442号复制组、251号Chunk的2127752103字节偏移处,长度为150148字节,CRC校验码为57583d02,签名5844d73fNaca4af3d用于防止URL篡改攻击。

    图片系统

    基于JFS小文件存储系统,我们在2014年春天重新建设了京东商品图片系统(系统架构如图3所示),并在公司上市之前成功上线。之后,图片系统零故障稳定运行至今,历经商品图片规模从十亿到百亿的大幅增长。
    同一张商品图片可能有数十种不同的规格(不同的设备、展现格式、降质参数),但源站JFS只存一副原图,CDN会缓存各种规格的图片URL,CDN未命中的图片则进行回源实时处理并返回。这样不仅节约了源站JFS的存储空间,也可以灵活地满足业务不断变化的需求。

    这里写图片描述

    图3 京东新图片系统架构

    在解决最核心的图片存储和处理问题后,我们也做了很多工作来推动图片技术的发展。在缩放效率上,引入ICC、IPP编译将图片缩放性能提升到最初的3倍以上。在流量优化方面,将Webp格式引入京东,与无线部门紧密合作,将移动端的图片全部替换成Webp格式,给用户节省约35%的下行流量,并显著提升了用户体验。

    大文件存储

    JFS V2实现大文件存储功能。对于大文件写操作来说,类Paxos复制协议并不合适。primary拿到数据后同时发送给两个follower,这样primary的带宽资源将成为系统的瓶颈。因此,在大文件存储复制协议的选择上,JFS采取了链式复制(Chained Replication)以提高写操作吞吐量。链式复制结构如图4所示。在数据发送和接收上,也均使用了流水线处理,进一步提高了数据传输效率。

    这里写图片描述

    图4 JFS大文件复制协议

    在数据存储结构设计上,恰恰与小文件相反,将一个大文件分成多个块来存储,这样可以规避局部过热的文件造成单机磁盘I/O过载;另外,分成多块也更利于整个系统资源的调度。大文件的数据存储如图5所示。

    这里写图片描述

    图5 JFS大文件数据存储

    对象存储服务

    JFS的小文件存储和大文件存储功能,从可靠性、可用性和稳定性方面,已经满足了大部分的业务需求,但使用起来却不是很方便,上传和下载都需要通过SDK,用户排查问题不是那么便捷,且对多语言的支持也不好。我们构建了JFS V3产品形态:简单对象存储,支持HTTP协议;支持文本、图片、视频等任何类型数据的存储;支持1个字节到1TB大小的数据存储;支持List操作,用户数据可以有层次结构。JFS V3为众多业务场景提供了最便捷的数据访问方式。

    对象存储系统架构如图6所示。除了前面已经提到的大小文件存储,还需要构建Gateway、账户和Bucket管理、日志处理等,当然还有最复杂的元数据管理。

    对象存储的元数据管理是一个业内难题。虽然对象存储并无目录的概念,但要支持按前缀进行List的操作,即能通过Prefix和Delimiter的结合,实现层次查询,是有一定难度的。在数据量不大时,类似于Hdfs的NameNode将全部用户Key都存在内存中就能满足需求,但当对象的数量超过十亿时,将会耗尽内存,无法做到横向扩展。很多KV存储能做到随意横向扩展,却不能很好地支持对象存储List请求。

    这里写图片描述

    图6 对象存储架构

    JFS V3采用JED(京东弹性数据库)和JIMDB(京东内存存储系统)组合,来实现对象存储元数据的有效管理。将元数据扁平化持久存储在弹性数据库JED中,热点缓存在JIMDB中,一方面利用JED的单库MySQL的B树结构实现元数据的List层次查询;另一方面使用JIMDB实现高速单Key查询。当数据量达到一定阈值时,JED可以进行在线的扩容与重新分片,JIMDB也可以做动态容量扩展,这使得JFS V3服务逻辑层在工程实现上非常简单。

    电子签收

    JFS V3作为对象存储服务,一经推出就受到业务部门的广泛欢迎,电子签收小票的存储管理就是一个特别典型的应用。

    从环保和成本的角度出发,运营系统青龙研发部创新性地启动了电子签收项目,取代之前每天数百万张的纸质小票。电子签收产生的海量签名图片需要高安全性、高稳定性、高持久性地保存。这无疑是对象存储的一个很好的应用场景,在此之上我们还实现了加解密、文字转图片、图片合成等定制化需求。基于JFS对象存储的电子签收后台系统,根据传回来的签收信息,按照指定样式生成签收小票图片并与用户签名图片合成,再按照业务安全性要求做数据加解密处理。如图7所示。

    这里写图片描述

    图7 电子签收

    经过过去4年的发展,JFS对象存储目前支持京东1200多个业务的数据存储,双11最高峰值为每秒约10万个对象同时读写,存储对象数目达数百亿级别,数据总量达数十PB。

    本文节选自:《京东基础架构建设之路(全彩)》一书;
    这里写图片描述
    编辑推荐:
    1. 从无到有的架构建设之路,逐步解决业务痛点;
    2. 一线架构师的前线战报,为618、11.11保驾护航;
    3. 全面解析京东基础架构技术,承载亿级规模存储和流量的基础架构实践;
    4. 集诸多热点技术之大成:容器/数据库/存储/中间件/全链路军演/异地多- 活/电商中的机器学习应用。

    展开全文
  • 操作系统之文件管理

    千次阅读 多人点赞 2020-09-22 03:05:15
    信息项:构成文件内容的基本单位(单个字节,或多个字节),各信息项之间具有顺序关系 文件内容的意义:由文件建立者和使用者解释 1.2 如何设计一个文件系统 这里先看文件管理的需求: 从用户角度 文件系统是...

    一、文件与文件系统

    1.1 文件是什么

    • 文件是对磁盘的抽象
    • 所谓文件是指一组带标识(标识即为文件名)的、在逻辑上有完整意义的信息项的序列。
    • 信息项:构成文件内容的基本单位(单个字节,或多个字节),各信息项之间具有顺序关系
    • 文件内容的意义:由文件建立者和使用者解释

    1.2 如何设计一个文件系统

    这里先看文件管理的需求:

    • 从用户角度

      文件系统是如何呈现在用户面前:

      *   一个文件的组织
      
      • 如何命名
      • 如何保护文件
      • 可以实施的操作
    • 从操作系统角度:怎样组织、管理文件

      *   文件的描述、分类
      
      • 文件目录的实现
      • 存储空间的管理
      • 文件的物理地址
      • 磁盘实际运作方式(与设备管理的接口)
      • 文件系统的性能

    1.3 文件系统

    • 操作系统中统一管理信息资源的一种软件,管理文件的存储、检索、更新,提供安全可靠的共享和保护手段,并且方便用户使用

    • 文件系统要完成哪些任务

      1、统一管理磁盘空间,实施磁盘空间的分配与回收

      2、实现文件的按名存取:名字空间–映射–>磁盘空间

      3、实现文件信息的共享,并提供文件的保护、保密手段

      4、向用户提供一个方便使用、易于维护的接口,并向用户提供有关统计信息

      5、提高文件系统的性能

      6、提供与IO系统的统一接口

    1.4 文件的分类

    按文件性质和用途分类(UNIX),一般分为普通文件、目录文件、特殊文件(设备文件)、管道文件、套接字

    • 普通文件

      即用户自己建立的文件,包含了用户的信息,一般为ASCII或二进制文件

    • 目录文件

      管理文件系统的系统文件

    • 特殊文件

      字符设备文件:和输入输出有关,用户模仿串行I/O设备,例如终端、打印机、网卡等。

      块设备文件:磁盘

    1.5 文件的逻辑结构

    • 无结构的流式文件
      对文件内信息不再划分单位,它是依次的一串字符流构成的文件。
    • 有结构的记录式文件
      用户把文件内的信息按逻辑上独立的含义划分信息单位,每个单位称为一个逻辑记录(简称记录)。


    **说明:**这里是从用户角度看文件,由用户的访问方式确定,这里给出了三种逻辑结构,还可以组织成堆、顺序、索引、索引顺序、散列等结构。第一种是以字节为单位的流式结构,第二种是一种记录式文件结构,最后一种是树形结构。

    1.6 典型的文件逻辑结构与文件存取

    • 流式文件:构成文件的基本单位是字符

      文件是有逻辑意义、无结构的一串字符的集合

    • 记录式文件:文件由若干记录组成,可以按记录进行读写、查找等操作。每条记录有其内部结构

    • 文件的逻辑结构与文件存取之间的关系

      顺序存取(访问)

      随机存取:提供读写位置(当前位置)。如UNIXseek操作。

    1.7 文件的存储介质

    1.7.1 存储介质与物理块

    • 典型的存储介质

      磁盘(包括固态盘SSD)、磁带、光盘、U盘、…

    • 物理块(块block、簇cluster

      信息存储、传输、分配的独立单位

      存储设备划分为大小相等的物理块,统一编号

    1.7.2 典型的磁盘结构

    普通磁盘构造及工作原理

    • 磁道(Track)
    • 柱面(Cylinder)
    • 扇区(Sector)
    • 磁头(Heads)
    • 盘片(Platters)
    • 每个碟片都有两面,因此也会相对应每碟片有2个磁头。

    • A:磁道
    • B:扇面
    • C:扇区
    • D:簇(扇区组)
      在硬盘上定位某一数据记录位置—C扇区,使用了三维定位。

    1.7.3 磁盘访问

    磁盘工作时盘片在高速旋转,机械手臂驱动磁头沿着径向移动,在磁道上读取所需要的数据。
    一次访问磁盘的请求:读写、磁盘地址(设备号、柱面号、磁头号、扇区号),内存地址(源/目)。完成过程由三个动作组成:

    1. 寻道(时间):磁头移动定位到指定磁道
    2. 旋转延迟(时间):等待指定扇区从磁头下旋转经过
    3. 数据传输(时间):数据在磁盘与内存之间的实际传输

    1.7.4 磁盘空间管理

    • 位图

      用一串二进制位反映磁盘空间中分配使用情况,每个物理块对应一位,分配的物理块为0,否则为1

      申请物理块时,可以在位示图中查找1的位,返回对应的物理块号

      归还时,将对应位转置1

    • 空闲块表

      将所有空闲块记录在一个表中,即空闲块表

      主要两项内容:起始块号,块数

    • 空闲块链表

      把所有空闲块链成一个表

      扩展:成组链接法

    磁盘地址与块号的转换

    成组链接法设计思想

    **说明:**左上角的是一个专用块,表示一些有用信息,而右边大括号中的都是空闲块。所有空闲块我们分成了若干组,典型的是100块是一组,最后一个空闲组只有99个空闲块。专用块中有20个空闲块号,分别对应右边的空闲块组。每次要使用文件的时候,就从专用块中挑选空闲块,一般从801开始分配。820中的第一块实际上是记录了后面一块800中空闲块的空闲块号和总的空块的数量,后面的以此类推。最后一个组中的0则表示最后一组的标志。

    成组链接法:分配算法

    分配一个空闲块

    L单元(空闲块数)

    • 空闲块数 > 1 , i = L + 空闲块数

      从i单元得到一个空闲块号;

      把该块分配给申请者;

      空闲块数减1

    • 空闲块数 = 1, 取出L + 1单元内容(一组的第一块号或0);

      值 = 0无空闲块,申请者等待

      其值不等于零,把该块内容复制到专用块

      该块分配给申请者;

    把专用块内容读到内存L 开始的区域。

    成组链表法:回收算法

    归还一块

    L单元的空闲块数

    • 空闲块数 < 100空闲块数加一;

      j := L + 空闲块数

      归还块号填入j单元

    • 空闲块数 = 100, 则把内存中登记的信息写入归还块中;

      把归还块号填入L+ 1单元;

      L单元置成1

    二、文件控制块和文件目录

    2.1 文件属性

    • 文件控制块(File Control Block:FCB

      为管理文件而设置的数据结构,保存管理文件所需的所有有关信息(文件属性或元数据)

    • 常用属性

      文件名,文件号,文件大小,文件地址,创建时间,最后修改时间,最后访问时间,保护,口令,创建者,当前拥有者,文件类型,共享计数,各种标志(只读、隐藏、系统、归档、ASCII/二进制、顺序/随机访问、临时文件、锁)

    • 基本文件操作

    ![](https://img-blog.csdnimg.cn/img_convert/a5a3c601b9b7e0d0d85df16a22b7d1ea.png)
    6

    2.2 文件目录、目录项与目录文件

    • 文件目录

      *   统一管理每个文件的元数据,以支持文件名到文件物理地址的转换
      
      • 将所有文件的管理信息组织在一起,即构成文件目录
    • 目录文件

      将文件目录以文件的形式存放在磁盘上

    • 目录项

      *   构成文件目录的基本单元
      
      • 目录项可以是FCB,目录是文件控制块的有序集合

    2.3 文件目录结构的演化


    **说明:**最初是以一级目录结构,最后慢慢演化成了树形目录结构。

    2.4 与目录相关的概念

    • 路径名

      绝对路径名:从根目录开始

      相对路径:从当前目录开始

    • 当前目录/工作目录

    • 目录操作

      创建目录、删除目录等等

    2.4 目录文件之间的关联

    三、文件的物理结构

    文件在存储介质上的存放方式

    主要解决两个问题:

    • 假设一个文件被划分成N块,这N块在磁盘上是怎么存放的?
    • 其地址(块号或簇号)在FCB中是怎样记录的?

    3.1 连续(顺序)结构

    • 文件的信息存放在若干连续的物理块中

    在上图a中,存放者多个连续的文件,在b中有些磁盘空间被还回来了。如果有些块太小,可能就不能再利用了。在FCB中我们只需要给出文件块的首地址和块数即可。

    • 优点

      简单

      支持顺序存取和随机存取

      所需的磁盘寻道次数和寻道时间最少

      可以同时读入多个块,检索一个块也很容易

    • 缺点

      *   文件不能动态增长,因为可能后面的磁盘空间已经被占据了。如果要增长则需要给出预留空间,但是这样就导致了浪费或重新分配和移动的开销。
      
      • 不利于文件插入和删除
      • 产生外部碎片:可以使用紧缩技术进行整理

    3.2 链接结构

    • 一个文件的信息存放在若干不连续的物理块中,各块之间通过指针连接,前一个物理块指向下一个物理块

    **说明:**在FCB中我们只需要给出第一块的块号即可。

    • 优点

      *   提高了磁盘空间的利用率,不存在外部碎片问题
      
      • 有利于文件插入和删除
      • 有利于文件动态扩充
    • 缺点

      *   存取速度慢,不适于随机存取
      
      • 可靠性问题,如指针出错
      • 更多的寻道次数和寻道时间
      • 链接指针占用一定的空间

    于是我们可以对此种结构进行某种改造:文件分配表FAT

    3.3 文件分配表(FAT)

    ![](https://img-blog.csdnimg.cn/img_convert/1e0fedc71930f24dc0ed2763d414ee1e.png)
    11

    **说明:**是把所有物理块的表指针都几种存放在一张表中,而不是用一个物理块的一部分来存放指针。从图中可以看到文件A的块号是4,而其下一个物理块的表项为7,最后到值为-1则表示结束。那某文件的起始块号从哪里得到?其实起始块号就记录在了FCB中。这种结构一般用在Windows中。在UNIX中一般采用索引结构。

    3.4 索引结构

    • 一个文件的信息存放在若干个不连续物理块中
    • 系统为每个文件建立一个专用数据结构:索引表,并将这些物理块的块号存放在该索引中。
    • 索引表就是磁盘块地址数组,其中地i个条目指向文件的第i块。

    那索引表应该存放在何处?

    这里必须知道每个文件的索引表长度是不一样的,于是不能存放在FCB中,因为FCB是固定大小的。于是我们在FCB中只记录索引表的地址。

    ![](https://img-blog.csdnimg.cn/img_convert/f1a3f40e4630f06f6cf7efc01a6f6e31.png)
    12

    **说明:**文件B的索引块号是24,索引表是存放在一个物理块中的。索引块中就记录了分配给这个文件的物理块号,可以看到这里我们是可以随机存取的。

    • 优点

      保持了链接结构的优点,又解决了其缺点

      *   既能顺序存取,又能随机存取
      
      • 满足了文件动态增长、插入删除的要求
      • 能充分利用磁盘空间
    • 缺点

      *   较多的寻道次数和寻道时间
      
      • 索引表本身带来了系统开销,如:内存、磁盘空间、存取时间
    • 组织方式

      问题:索引表很大,需要多个物理块存放时怎么办?

      *   1、链接方式
      
      一个盘块存一个索引表,多个索引表链接起来
      
      • 2、多级索引方式

        将文件的索引表地址放在另一个索引表中

      • 3、综合模式

        直接索引方式与间接索引方式结合

    • 多级索引与综合模式

    ![](https://img-blog.csdnimg.cn/img_convert/0153ee1b94be16ef7eb08991eecf654f.png)
    13

    **说明:**图上部分是多级索引模式,此模式中顶级索引表中都记录的是次级索引表地址。而在图下部分则是综合模式,顶级索引表中一部分记录的是直接的物理块,而另一部分是记录的次级索表块地址,即一部分是直接寻址,一部分是间接寻址。

    3.5 UNIX的三级索引结构

    UNIX文件系统中采用的是多级索引结构(综合模式)

    • 每个文件的主索引表有15个索引项(FCB中),每项两个字节

    • 12项直接存放文件的物理块号(直接寻址)

    • 如果文件大于12块,则利用第13项指向一个物理块,在该块中存放的是一级索引表。假设扇区大小为512字节,物理块等于扇区块大小,一级索引表可以存放256个物理块号

    • 对于更大的文件还可以利用第14项和第15项作为二级和三级索引表

    • 问题:采用这种结构,一个文件最大可以达到多少个物理块

    ![](https://img-blog.csdnimg.cn/img_convert/fe14a133d7e56c27b49ba7535fe8838a.png)
    14

    四、文件系统的实现

    4.1 概述

    • 实现文件系统需要考虑磁盘上和内存中的内容布局

    • 磁盘上

      如何启动操作系统?

      磁盘是怎样管理的?怎样获取磁盘的有关信息?

      目录文件在磁盘上怎么存放?普通文件在磁盘上怎么存放?

    • 内存中

      当进程使用文件时,操作系统是如何支持的?

      文件系统的内存数据结构

    4.2 相关术语

    • 磁盘分区

      把一个物理磁盘的存储空间划分为几个相互独立的部分,称为分区

    • 文件卷

      磁盘上的逻辑分区,由一个或多个物理块组成。

      *   一个文件卷可以是整个磁盘或部分磁盘或跨盘(`RAID`)
      
      • 同一个文件卷使用同一份管理数据进行文件分配和磁盘空闲空间管理,不同的文件卷中的管理数据是相互独立的。
      • 一个文件卷上包括文件系统信息、一组文件(用户文件、目录文件)、未分配空间
      • 块或簇:一个或多个(2的幂次方)连续的扇区,可寻址数据库
    • 格式化

      在一个文件卷上建立文件系统,即建立并初始化用于文件分配和磁盘空闲空间管理的管理数据

    4.3 磁盘上的内容

    ![](https://img-blog.csdnimg.cn/img_convert/5231db71101d3c6215c3f0dbd523b7cf.png)
    15
    • 引导区

      包括了从该卷引导操作系统所需的信息,每个卷(分区)都有一个,通常称为扇区

    • 卷信息

      包括该卷的块数、块大小、空闲块数量和指针、空闲FCB数量和指针等等

    • 目录文件

    4.4 磁盘上文件系统的布局

    ![](https://img-blog.csdnimg.cn/img_convert/e6c9367122e635f8fa26e230cd5f8fe3.png)
    16

    4.5 内存中所需的数据结构(以UNIX为例)

    ![](https://img-blog.csdnimg.cn/img_convert/ba5a0519175e4b1060a482df29f72a8d.png)
    17

    五、文件系统实例(UNIX)

    5.1 文件目录检索

    访问一个文件–>两步骤

    • 目录检索

      用户给出文件名–>按文件名查找到目录项/FCB

      根据路径名检索:

      • 全路径名:从根目录开始
      • 相对路径:从当前目录开始
    • 文件寻址

      根据目录想/FCB中文件物理地址等信息,计算出文件中任意记录或字符在存储介质上的地址

    5.2 目录文件实现时的改进

    • 问题:如何加快目录检索?

    • 一种解决方案

      目录项分解法:即把FCB分成两部分

      • 符号目录项:文件名,文件号

      • 基本目录项:除文件名外的所有字段

    ![](https://img-blog.csdnimg.cn/img_convert/f8f81a2e88c900ac547c9ac845283e16.png)
    18
    **说明:**每个方格表示目录文件(由目录项组成),每个椭圆表示普通文件。如何我们采用目录项分解法,于是符号目录项中的内容就特别简单,此时目录项就变成了符号目录项;基本目录项保存在了磁盘的专用区域。
    
    • 好处

      假设一个FCB48个字节,物理块大小512字节。符号目录项占8字节(文件名6字节,文件号2字节),基本目录项占48-5 = 42字节。

      这里给出一个目录文件有128个目录项,在分解前则需要13个物理块,分解后符号目录项占2块,基本目录项占11块。总块数是不变的,但是查找一个文件的平均访问磁盘的次数分解前为(1+13)/2=7次,分解后为(1+2)/2 + 1 = 2.5次。于是就提高了文件检索的速度。

    六、UNIX文件系统

    • FCB= 目录项 +i节点

    • 目录项:文件名 +i节点号

    • 目录文件由目录项构成

    • i节点:描述文件的相关信息

    • 每个文件由一个目录项、一个i节点和若干磁盘块构成

    ![](https://img-blog.csdnimg.cn/img_convert/b6ddd2603da2a6bfce85b0d646f84aa2.png)
    19

    **说明:**上图是UNIX系统的文件布局。下面看如何查找一个文件

    <div class="image-package">
    
    ![](https://img-blog.csdnimg.cn/img_convert/300601862d4d453ecb8507ca4191ffd4.png)
    20

    **说明:**要查找的文件为/usr/ast/mbox,根目录文件中一个点表示本目录的目录项,两个点表示父目录的目录项,每个目录项都包含文件名和i节点号。从i节点中可以知道这个文件的第一块存放在128这个位置,于是我们读取usr中的内容,从这个目录中去找ast这个文件,以此类推。

    一、文件系统实例(FAT)

    1.1 Windows的FAT16文件系统

    • 簇(块)大小:1、2、4、8、16、3264扇区

    • 文件系统的数据记录在“引导扇区”中

    • 文件分配表FAT的作用

      描述簇的分配状态、标注下一簇的簇号等

    • FAT表项:2字节(16位)

    • 目录项:32字节

    • 根目录大小固定

    ![](https://img-blog.csdnimg.cn/img_convert/4843c080d6c11860635c5a07169a935f.png)
    1

    1.2 FAT文件系统:主引导记录(Main Boot Record,MBR)

    • 主引导记录

      一般放在零号扇区中

    ![](https://img-blog.csdnimg.cn/img_convert/65e5275a0ecf5db0a3acd3f5a00c2c03.png)
    2

    1.3 FAT文件系统:分区引导扇区(Dos Boot Record,DBR)

    ![](https://img-blog.csdnimg.cn/img_convert/753992dff87da2a053e08f1c781f44e9.png)
    3

    **说明:**这里是以FAT32为例。

    1.4 引导扇区(BIOS参数块)

    **说明:**这里我们看BIOS参数块,也是以FAT32为例。

    1.5 引导扇区(扩展BIOS参数块EBPB)

    1.6 文件分配表FAT

    • 可以把文件分配表看成是一个整数数组,每个整数代表磁盘分区的一个簇号

    • 状态

      未使用、坏簇、系统保留、被文件占用(下一簇簇号)、最后一簇(0xFFFF

    • 簇号从0开始编号,簇0和簇1是保留的。

    1.7 FAT16目录项

    **说明:**在前面讲过,UNIX系统中i节点加上目录项就是FCB,而在FAT文件系统中FCB就等于目录项。32个字节没有用完,没用完的保留。

    1.8 FAT32文件系统

    • FAT32中,根目录区(BOOT区)不是固定区域、固定大小,而是数据区的一部分,采用与子目录文件相同的管理方式

    • 目录项仍占32字节,但分为各种类型(包括:“.”目录项、“..”目录项、短文件名目录项、长文件名目录项、卷标项(根目录)、已删除目录项(第一字节为0xE5)等)

    • 支持长文件名格式

    • 支持Unicode

    • 不支持高级容错特性,不具有内部安全特性

    1.9 FAT32目录项

    **说明:**这是一个基本的目录项。

    1.10 一般长文件名的实现方式

    **说明:**左边的实现是目录项的长度不固定。第一个字段给出目录项的长度,然后把固定长度的属性记录在其后,再才是文件名,因为文件名的长度是不一样的,留出足够的空间给文件名。缺点就是一个文件删除时,就留出了一块空间,而这个空间可能不能放下其他文件,这样就会产生碎片。右边的实现是由于文件名的长度不固定,所以我们希望每个目录项的大小是固定的,其中包含了一个指向文件名起始地址的指针,然后是文件的相关属性,所有的文件名都存放在另一个区域(堆)。

    1.11 FAT32中长文件名目录项格式

    ![](https://img-blog.csdnimg.cn/img_convert/b13c1680b55d6d985dd4e2d9536c3690.png)
    11

    **说明:**其中有三处地方分别记录了文件名。前5个字符(采用的是Unicode编码,则两个字节代表一个字符)保存文件名的前5个字符,于是一共可以保存13个字符。如果一个长文件名目录项不够,则需要用第二个。在第一个字段中第6位来记录是否是最后一个目录项。下面看一个例子,文件名为The quick brown.fox,采用Unicode编码。

    **说明:**其实这样一个文件占用了三个目录项。第一个目录项就是短文件名目录项,后面的两个目录项主要保存文件名。再看一个更长的文件名文件例子:

    **说明:**这里的文件名更长,需要占用五个目录项。

    二、文件操作的实现

    这里主要是以UNIX操作系统为例。

    2.1 文件操作的实现

    • 创建文件

      建立系统与文件的联系,实质是建立文件的FCB

      *   在目录中为新文件建立一个目录项(在`UNIX`中还需要`i`节点),根据提供的参数及需要填写相关内容
      
      • 分配必要的存储空间
    • 打开文件

      根据文件名目录中检索,并将该文件的目录项读入内存,建立相应的数据结构,为后续的文件操作做好准备。打开文件后一般会返回一个值,这个值一般叫文件描述符或文件句柄,之后的操作是通过文件描述符来进行的。

    2.2 文件操作:建立文件

    create(文件名,访问权限)

    • 1、检查参数的合法性

      例如:文件名是否符合命名规则;有无重名文件,合法则进行下一步,否则报错返回。

    • 2、申请空闲目录项,并填写相关内容

    • 3、为文件申请磁盘块

    • 4、返回

    2.3 文件操作:打开文件

    为文件读写做准备:给出文件路径名,获得文件句柄(file handler)或文件描述符(file descripter),需将该文件的目录项读到内存fd = open(文件路径名,打开方式)

    • 1、根据文件路径名查目录,找到目录项(或i节点号)
    • 2、根据文件号查系统打开文件表,看文件是否已被打开,如果是,则共享计数加一,否则,将目录项(或i节点)等信息填入系统打开文件表空表项,共享计数置为一。
    • 3、根据打开方式、共享说明和用户身份检查访问合法性
    • 4、在用户打开文件表中获取一空表项,填写打开方式等,并指向系统打开文件表对应表项,返回信息:fd(文件描述符,是一个非负整数,用于以后读写文件)

    2.4 文件操作:指针定位

    seekfd, 新指针位置):系统为每个进程打开的每个文件维护一个读写指针,即相对于文件开头的偏移地址(读写指针指向每次文件读写的开始位置 ,在每次读写完成后,读写指针按照读写的数据量自动后移相应的数值)

    • 1、由fd查用户打开文件表,找到对应的表项
    • 2、将用户打开文件表中文件读写指针位置设为新指针的位置,供后继读写命令存取该指针处文件内容。

    2.5 文件操作:读文件

    read(文件描述符,读指针,要读的长度,内存目的地址)

    • 1、根据打开文件时得到的文件描述符,找到相应的文件控制块(目录项),确定读操作的合法性,读操作合法则进行下一步,否则出错处理。
    • 2、将文件的逻辑块号转换为物理块号。根据参数中的读指针、长度与文件控制块中的信息,确定块号、块数、块内位移
    • 3、申请缓冲区
    • 4、启动磁盘I/O操作,把磁盘块中的信息读入缓冲区,再送到指定的内存区(多次读盘)
    • 5、反复执行3、4直至读出所需数量的数据或读至文件尾

    三、文件系统的管理

    3.1 文件系统的可靠性

    可靠性:抵御和预防各种物理性破坏和人为性破坏的能力

    • 块坏问题

    • 备份

      通过转储操作,形成文件或文件系统的多个副本。

    3.2 文件系统备份

    • 全量转储

      定期将所有文件拷贝到后援存储器

    • 增量转储

      只转储修改过的文件,即两次备份之间的修改。减少系统开销。

    • 物理转储

      从磁盘第零块开始,将所有磁盘块按序输出到磁带

    • 逻辑转储

      从一个或几个指定目录开始,递归地转储子给定日期后所有更改的文件和目录

    3.3 文件系统一致性

    • 问题的产生:

      磁盘块–>内存–>写回磁盘块

      若在写回之前,系统崩溃,则文件系统出现不一致

    • 解决方案

      设计一个使用程序,当系统再次启动时,运行该程序,检查磁盘块和目录系统

    3.4 磁盘块的一致性检查

    **说明::**一致性检查时,检查所有的文件和空闲块,检查完之后可能会出现四种结果。第一种是一个一致性的结果,即某个磁盘块要么分配给了某个文件,要么在空闲块中。第二种结果是在空闲块中找不到,但是也没有分配给某个文件,于是我们通过在空闲块表中将磁块标记为一来解决。第三种结果是某个磁盘块在空闲块表中出现了两次,同样是不合理的,对这一位进行修改。最后一种结果是在两个文件中出现,这种情况较为复杂,我们应该在空闲块中找一个,然后将其中一个磁盘块内容拷贝到这个空闲块中,然后将使用块表中的这一位减一。

    3.5 文件系统的写入策略

    对某些文件做出了修改,那么什么时候将修改后的内容写入到文件中。这里需要考虑文件系统一致性和速度。下面有几种写入策略

    • 通写(write-through

      内存中的修改立即写到磁盘。缺点是速度性能差,如FAT文件系统。

    • 延迟写(lazy-write

      利用回写(write back)缓存的方法得到高速。其缺点就是可恢复性较差,可能会导致信息丢失

    • 可恢复写(tansaction log

      采用事务日志来实现文件系统的写入,既考虑安全性,又考虑速度性能,如NTFS

    四、文件系统的安全性

    这里我们讨论如何确保未经授权的用户不能存取某些文件?

    4.1 文件保护机制

    • 用于提供安全性、特定的操作系统机制
    • 对拥有权限的用户,应该让其进行相应的操作,否则,应禁止
    • 防止其他用户冒充对文件进行操作

    于是在实现的时候需要考虑用户身份验证和访问控制。对于用户身份我们可以采用比如密码、口令等方式。

    4.2 文件的访问控制

    有不同的访问控制手段,比如主动控制(使用访问控制表)和能力表(使用权限表)。

    • 主动控制

      每个文件一个

      记录用户ID和访问权限

      用户可以是一组用户

      文件可以是一组文件

    • 能力表

      每个用户一个

      记录文件名及访问权限

      用户可以是一组用户

      文件可以是一组文件

    4.3 UNIX的文件访问控制

    采用文件的二级存取控制,审查用户的身份、审查操作的合法性

    • 第一级:对访问者身份的识别

      对用户分类:

      *   文件主(`owner`)
      
      • 文件主的同组用户(group
      • 其他用户(other
    • 第二级:对操作权限的识别

      对操作分类:

      *   读操作(`r`)
      
      • 写操作(w
      • 执行操作(x
      • 不能执行任何操作(-

    五、文件系统的性能

    5.1 文件系统的性能问题

    • 磁盘服务:速度成为系统性能的主要瓶颈之一。因此,在设计文件系统时应尽可能减少磁盘访问次数

    • 提高文件系统性能的方法:

      目录项(FCB)分解、当前目录、磁盘碎片整理、块高速缓存、磁盘调度、提前读取、合理分配磁盘空间、信息的优化分布、RAID技术等等

    5.2 提高文件系统性能:块高速缓存(BLOCK CACHE)

    又称为文件缓存、磁盘高速缓存、缓冲区高速缓存。是指在内存中为磁盘块设置的一个缓冲区,保存了磁盘中某些块的副本。当对文件系统进行操作的时候:

    • 检查所有的读请求,看所需块是否在块高速缓冲中
    • 如果在,则可直接进行读操作;否则,先将数据块读入块高速缓存,再拷贝到所需的地方。
    • 由于访问的局部性原理,当一数据块被读入块高速缓存以满足一个I/O请求时,和可能将来还会再次访问到这一数据块。

    5.3 如何实现块高速缓存

    • 块高速缓存的组织方式

    **说明:**在块高速缓存中有若干个数据块,首先将这些块使用一个双向链表组织起来,当要访问这个链的时候就将其从此链中拿出来,然后挂接到链尾,而我们对于某个文件使用的块要检查其是否在高速缓存中,所以这里又使用块号进行散列以提高检查速度。

    • 块高速缓存的置换问题(修改LRU

      因为此缓存的空间肯定是不会很大的,所以当其满时我们需要对其进行置换。对于以后可能会再次使用的块我们将其放在链尾,而对于使用概率很小的块可能就需要将其剔除。

    • 块高速缓存的写入策略

      在文件系统中,我们需要考虑该块是否会影响文件系统的一致性。这里如前面所讲,不同的操作系统采用了不同的一致性解决方案。

    • 提前读取

      *   思路:每次访问磁盘,多读入一些磁盘块
      
      • 依据:程序执行的空间局部性原理
      • 开销:较小(只有数据传输时间)
      • 具有针对性

    5.4 Windows的文件访问方式

    一般有下面三种方式:

    • 不使用文件缓存

      *   普通方式
      
      • 通过Windows提供的FlushFileBuffer函数实现
    • 使用文件缓存(块高速缓存)

      *   预读取。每次读取的块大小、缓冲区大小、置换方式
      
      • 写回。写回时机选择、一致性问题
    • 异步模式

      *   不再等待磁盘操作的完成。
      
      • 使处理器和I/O并发工作

    用户对磁盘的访问通过访问文件缓存来实现:

    • WindowsCache Manager实现对缓存的控制

      *   读取数据的时候预取
      
      • Cache满时,根据LRU原则清除缓存的内容
      • 定期更新磁盘内容使其与Cache一致(每秒)
    • write-back机制

      *   在用户要对磁盘写数据时,只更改`Cache`中的内容,由`Cache Manager`决定何时将更新反映到磁盘
      

    5.5 提高文件系统性能:合理分配磁盘空间

    分配磁盘块时,把有可能顺序存取的块放在一起(尽量分配在同一柱面上,从而减少磁盘臂的移动次数和距离)

    **说明:**我们读取文件系统时,每次都要先找到i节点区,然后再去找到文件位置,如果i节点区在最外道,而相关文件在最里道,则在读取的时候磁臂就需要不断的移动,这样显示效率低下。一种解决方案如(a),我们将i节点区和相关文件放在距离较近的磁道上;另一种是如(b),首先将磁道分成了若干组,然后将i节点区也划分成若干部分,每一组磁道都有一个i节点区,而每个文件都和其i节点区在同一组,这样磁臂也不需要很大的移动。

    5.6 提高文件系统性能:磁盘调度(重点)

    当有多个访盘请求等待时,采用一定的策略,对这些请求的服务顺序调整安排,从而降低平均磁盘服务时间,达到公平、高效的目的。

    • 公平

      一个IO请求在有限时间内满足

    • 高效

      减少设备机械运动带来的时间开销

    一次访盘时间 = 寻道时间 + 旋转延迟时间 + 传输时间

    • 减少寻道时间
    • 减少延迟时间

    5.7 磁盘调度算法(重点)

    例子:假设磁盘访问序列:98、183、37、122、14、124、65、67,这些数字表示柱面号或磁道号。读写头起始位置为53。请计算磁头服务序列和磁头移动总距离(道数)。下面使用几种算法进行计算:

    • 1、先来先服务(FCFS

      按访问请求到达的先后次序服务

      *   优点:简单、公平
      
      • 缺点:效率不高,相邻两次请求可能会造成最内到最外的柱面寻道,使磁头反复移动,增加了服务时间,对机械也不利。

      磁道服务序列和访问序列一致,磁头移动总距离为640,平均80

    • 2、最短寻道时间优先(Shortest Seek Time First)(重点)
      用于磁盘
      优先选择距当前磁头最近的访问请求进行服务,主要考虑寻道优先。

      • 优点
        改善了磁盘平均服务时间
      • 缺点
        造成某些访问请求长期等待而得不到服务
    • 3、扫描算法(SCAN电梯算法)(重点)

      当设备无访问请求时,磁头不动;当有访问请求时,磁头按一个方向移动,在移动过程中遇到的访问请求进行服务,然后判断该方向上是否有访问请求,如果有则继续扫描;否则改变移动方向,并为经过的访问请求服务,如此反复。其实是一种对距离和方向的折中算法。

    • 4、单向扫描算法(C-SCAN

      这是对扫描算法的一种改进。

      *   总是从零号柱面开始向里扫描
      
      • 按柱面(磁道)位置选择访问者
      • 移动臂到达最后一个柱面后,立即带动读写磁头快速返回到零号柱面
      • 返回时不为任何的等待访问者服务
      • 返回后可再次进行扫描

    主要的目的是减少了新请求的最大延迟。

    • 5、N-step-SCAN策略

      • 把磁道请求队列分成长度为N的子队列,每一次用SCAN处理一个子队列
      • 在处理某一个队列时,新请求添加到其他子队列中
      • 如果最后剩下请求数小于N,则它们全部都将在下一次扫描时处理
      • N值比较大时,其性能接近SCAN;当N = 1时,即FIFO

    主要是为了解决磁头臂的粘性问题。

    • 6、FSCAN策略

      • 使用两个子队列
      • 扫描开始时,所有请求都在一个队列中,而另一个队列为空
      • 扫描过程中,所有新到的请求都放入另一个队列中
      • 对新请求的服务延迟到处理完所有老请求之后

    主要是为了解决磁头臂的粘性问题。本算法及以上都是对磁臂移动的优化算法。

    • 7、旋转调度算法

      根据延迟时间来决定执行次序的调度。一般有三种情况:

      • 若干等待访问请求访问同一磁头上的不同扇区

      • 若干等待访问请求访问不同磁头上的不同扇区

      • 若干等待访问请求访问不同磁头上的相同扇区

        解决方案:

        • 对于前两种情况:总是让首先到达读写磁头位置下的扇区先进行传送操作
      • 对于第三种情况:这些扇区同时到达读写磁头位置下,可任意选择一个读写磁头进行传送操作

    5.8 提高文件系统性能:信息优化分布

    记录在磁道上的排列方式也会影响输入输出操作的时间。

    **说明:**如果信息是按左边那样分布的,那么如果首先读到1号记录,然后花5ms处理,但是此时磁盘已经转到了4号记录,于是如果我们要处理2号记录,则必须将4、5、6、7、8都旋转过去之后才能处理2号记录;而如果信息是按右边那样分布的,当处理完1号记录,而此时磁盘也刚好旋转到了2号记录处,这样就能极大的提高文件系统的性能。

    5.9 提高文件系统性能:记录的成组与分解

    • 记录的成组

      把若干个逻辑记录合成一组存放在一块的工作

    • 进行成组操作时必须使用内存缓冲区,缓冲区的长度等于逻辑记录长度乘以成组的块因子(成组的长度)。

    • 成组的目的:提高了存储空间的利用率;减少了启动外设的次数,提高系统的工作效率。

    • 记录的分解

      从一组逻辑记录中把一个逻辑记录分离出来

    典型的例子就是目录文件的存储。

    5.10 提高文件系统性能:RAID技术

    起始就是独立磁盘冗余阵列(Redundant Arrays of Independent Disks),就是将多块磁盘按照一定要求构成一个独立的存储设备。目的就是提高可靠性和性能。在实现时,需要考虑存储系统的速度、容量、容错、数据灾难发生后的数据恢复。

    • 数据是如何组织的

      *   通过把多个磁盘组织在一起,作为一个逻辑卷提供磁盘跨越功能
      
      • 通过把数据分成多个数据块,并行写入/读出多个磁盘,以提高数据传输率(数据分条stripe
      • 通过镜像或校验操作,提供容错能力(冗余信息的保存)
      • 最简单的组织方式是镜像,最复杂的是块交错校验。
    • 例1:RAID 0 - 条带化

      *   数据分布在阵列的所有磁盘上
      
      • 有数据请求时,同时多个磁盘并行操作
      • 充分利用总线宽带,数据吞吐率提高,驱动器负载均衡

    这种方式没有冗余信息保存,即无差错控制,性能是最佳的。

    • 例2:RAID 1-镜像

      *   最大限度保证数据安全和可恢复性
      
      • 所有数据同时存在与两块磁盘的相同位置
      • 磁盘利用率为50%

    9
    数据的安全性是最好的,但是磁盘利用率较低。
    
    • 例3:RAID 4-交错块奇偶校验

      *   带奇偶校验
      
      • 以数据块为单位


    数据保存在前四块盘上,而校验信息保存在第五块盘上。

    展开全文
  • Java字节码增强探秘

    千次阅读 2019-09-10 14:03:58
    1.字节码 1.1 什么是字节码? Java之所以可以“一次编译,到处运行”,一是...之所以被称之为字节码,是因为字节文件由十六进制值组成,而JVM以两个十六进制值为一组,即以字节为单位进行读取。在Java中一般是用ja...
  • windows下复制文件命令

    万次阅读 2012-06-14 10:04:40
    1、xcopy命令 复制文件和目录树。 XCOPY source [destination] [/A | /M] [/D[:date]] [/P] [/S [/E]] [/V] [/W]  [/C] [/I] [/Q] [/F] [/L] [/G] [/H] [/R] [/T] [/U]
  • 通过字节码分析JDK8中Lambda表达式编译及执行机制

    万次阅读 多人点赞 2016-04-23 13:07:01
    关于Lambda字节码相关的文章,很早之前就想写了,线上产品的后端技术,能快速迭代,除了得益于整体微服架构之外,语言层面上,也是通过Java8的lambda表达式的运用以及rxJava响应式编程框架,使代码更加简洁易维护,...
  • 纵观网上及冀云前辈那本书上的文章,发现已有的资料中存在有这么几个问题:1、无法实现0秒扫雷,都是至少需要1才能完成任务;2、雷区究竟是在游戏初始化时就设置好了,还是要等玩家点击了第一处雷区方块才进行设置...
  • Android大文件上传传之MD5篇

    千次阅读 2016-11-09 21:47:17
    前言现在越来越多的应用开始有上传大文件的需求,以及传,续传功能。由于最近学习大文件分隔上传,以及传的实现,给予分享的这种精神,我想将自己的学习过程,以及遇到的问题做一个总结,希望对有这方面需求的小...
  • Redis——Redis主从复制(工作流程详解)

    万次阅读 多人点赞 2021-04-18 20:53:12
    Redis主从复制主从复制简介主从复制的概念主从复制的作用主从复制工作流程阶段一:建立连接阶段主从连接(slave连接master)第一种方式第二种方式第三种方式授权访问阶段二:数据同步阶段工作流程数据同步阶段master...
  • 即便对那些有经验的Java开发人员来说,阅读已编译的Java字节码也很乏味。为什么我们首先需要了解这种底层的东西?这是上周发生在我身上的一个简单故事:很久以前,我在机器上做了一些代码更改,编译了一个JAR,并将...
  • MIDI文件格式分析(补充和勘误)

    千次阅读 2018-04-12 15:40:10
    MIDI文件格式分析(补充和勘误) 本文是对《MIDI文件格式分析》博客链接的一点补充: ...文件头一般包括文件的类型,因为Midi文件仅以.mid为扩展名的就有0类和1类两种,而大家熟悉的位图文件的格式就更多了,所以才会...
  •   注意:本文章主要是翻译自 FatFs 官网的 The basics of FAT filesystem。但是,原文大多都是文字说明,因此在翻译时,添加了大量的图片示例以及一些...FAT Filesystem FAT文件系统   This is a documentati...
  • 在oio和nio进行文件复制(zero-copy,直接从文件系统传输字节)效率对比的时候发现部分文件拷贝不全(以下只会展示client端代码); ioi代码如下: public static void main ( String [ ] args ) ...
  • 字节码指令看重写在JVM中的实现

    万次阅读 2015-07-30 19:22:35
    面向对象语言的继承、封装和多态的特性,在JVM中是怎样进行编译、解析,以及通过字节码指令如何确定方法调用的版本是本文如下要探讨的主要内容,全文围绕一个多态的简单举例来看在JVM中是如何实现的。
  • 目录前言参考文献代码 ...因为代码量较大,建议先把文件系统的逻辑以及各个专业术语的概念如FCB、FAT、用户打开文件表等搞懂再看代码,概念可以看书上p352的预备知识,或者看这篇博客:文件结构。 看完之后再手
  • redis主从之全量复制及增量复制

    千次阅读 2020-06-04 00:15:22
    对于主从复制的好处,在上篇文章我也写了,下面说一下注意事项。 注意事项: 安全 对于数据比较重要的节点,主节点会通过设置requirepass参数进行密码验证,这时候所有的客户端访问必须使用auth命令进行验证。从...
  • Linux下read和write函数复制一个文件

    千次阅读 2017-07-12 19:05:13
    Path参数是要打开或创建文件的名字。Oflag参数可用来说明此函数的多个选项。 下列一个或多个常量进行“或”运算构成oflag参数(这些参数在头文件中定义) 必选项: O_RDONLY 只读打开 O_WRONLY 只写打开 O_RDWR...
  • 下面是一位Java程序员的亲身经历,面试腾讯PCG部门处女面挂,但并未气馁,17天后竟拿下了字节跳动的offer,特献上面试真题,以供参考学习。 腾讯PCG部门,Java后台岗(处女面挂),出来就懵了 自我介绍 项目...
  • 超硬核!数据结构学霸笔记,考试面试吹牛就靠它

    万次阅读 多人点赞 2021-03-26 11:11:21
    实现统一功能两种算法:时间O(2^N),O(N^10),假设计算机可以运行10^7秒,每秒可执行基本操作10^5次,问可解问题规模各为多少?选哪个更为合适? 计算机一共可执行10^7*10^5=10^12次 第一种:n=log2,(10^12)=12log(2...
  • tar文件格式解析

    千次阅读 2019-06-28 15:34:15
    TAR是磁带存档程序 (tape archiver) 的首字母缩写。 Unix Tar是将多个文件存储为未... 单个tar文件包含多个记录,单个记录包含512个字节。虽然这种格式用于磁带上,但是也常用于其他媒体。 一个头记录代表单个归档...
  • 07_游戏破解器与文件加解密

    千次阅读 2022-04-03 14:25:33
    游戏破解器与文件加解密 Clion输出中文乱码终极解决方案: https://blog.csdn.net/qq_43302195/article/details/109009784 1. 游戏作弊器 工具的使用: 打开附件提供的修改器(Cheat Engine.exe) => 文件,打开进程...
  • redis配置文件中常用配置详解

    万次阅读 多人点赞 2019-05-29 23:38:44
    此次安装的版本为: 5.0.3 [root@localhost local]# redis-...Redis server v=5.0.3 sha=00000000:0 malloc=jemalloc-5.1.0 bits=64 build=afabdecde61000c3 打开redis.cof ###############################...
  • 第四章 文件系统 1.在早期的UNIX系统中,可执行文件(a.out)以一个非常特別的魔数开始,这 个...答:这些系统直接把程序载入内存,并且从word0(魔数)开始执行。为了避免将header作为代码执行,魔数是一条branch指令
  • 星际文件系统是一种点对点的分布式文件系统, 旨在连接所有有相同的文件系统的计算机设备。在某些方面, IPFS类似于web, 但web 是中心化的,而IPFS是一个单一的Bittorrent 群集, 用git 仓库分布式存储。换句话说, ...
  • 广告是支撑互联网高速发展的经济基石,也是很多互联网公司的重要收入来源。字节跳动的广告平台管理着 EB 量级的数据和服务着数以千万的商业用户,其中 ClickHouse 作为核心引擎支撑了...
  • 值为 everysec 时, 服务器在个事件循环都要将 aof_buf 缓冲区中的所有内容写入到 AOF 文件隔超过一秒就要在子线程中对 AOF 文件进行一次同步: 从效率上来讲, everysec 模式足够快, 并且就算出现...
  • 文件结构
  • 扩展名为bat的文件的创建

    千次阅读 2018-06-26 17:54:24
    一、在了解bat文件前要了解下DOS命令,DOS命令:计算机术语,是指DOS操作系统的命令,是一种面向磁盘的操作命令,主要包括目录操作类命令、磁盘操作类命令、文件操作类命令和其它命令。而bat文件就是把一系列的DOS...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 84,393
精华内容 33,757
关键字:

复制文件0字节每秒