本文使用「署名 4.0 国际 (CC BY 4.0)」许可协议,欢迎转载、或重新修改使用,但需要注明来源。 [署名 4.0 国际 (CC BY 4.0)](https://creativecommons.org/licenses/by/4.0/deed.zh) 本文作者: 苏洋 创建时间: 2023年01月21日 统计字数: 11136字 阅读时间: 23分钟阅读 本文链接: https://soulteary.com/2023/01/21/building-a-home-unraid-storage-server-at-low-cost-part-two.html ----- # 低成本搭建一台 Unraid 家庭存储服务器:中篇 虎年最后一篇文章,接着上一篇内容,聊聊如何提升硬件的易用性问题。 ## 写在前面 如果你的诉求非常简单、明确,不需要界面,上一篇内容中的 Ubuntu Server 应该已经能够完成你的诉求了。 但是,如果你和我一样,想要使用一个还算简洁漂亮的界面来管理配置和查看状态,可以考虑和我一样,使用简单的 WebUI 来解决问题(偷懒)。 ![完成部署后的 Unraid 控制面板首页](https://attachment.soulteary.com/2023/01/21/webui.jpg) 如果你已经选择搭建一台 Unraid 设备,可以直接阅读下一小节,如果你想了解影响我选择背后的其他因素,可以继续阅读下面的“系统选择”相关的内容。 ### 系统选择 Unraid vs TrueNAS or 其他 在前一篇文章和“在线讨论”中提到过,尽可能不想考虑使用相对“黑盒方案”或者非正版授权方案。所以,自带良好管理界面、[大量特性优化](https://learn.microsoft.com/zh-cn/windows-server/storage/file-server/file-server-smb-overview)的 Windows Server 版本,和被大量用户验证过的[群晖 DSM 界面](https://www.synology.com/en-global/dsm) 自然就被排除在外了。在排除了上面两个选项之后,拥有大量簇拥的 [TrueNAS](https://www.truenas.com/download-truenas-core/)(FreeNAS)和 [Unraid](https://unraid.net/download) 很自然地进入了决策范围。 这两个系统对于用户最大的硬件需求差异,**莫过于是否相对依赖 ECC 内存**。在上一篇内容发布之后,在文章的评论区也有过一些讨论。简单来说,是否使用 ECC 内存是影响用户选择 TrueNAS 的关键因素之一。 在[TrueNAS 的核心硬件指引文档](https://www.truenas.com/docs/core/gettingstarted/corehardwareguide/#error-correcting-code-memory)中,有重点说明过内存对于 TrueNAS 的重要性,一则是系统每一个组件都依赖内存来提升整体性能;二则是避免潜在的因为设备和内存本身的问题,导致的内存错误放大,引起的数据“转录”错误、数据落地丢失和损坏数据写入。 Unraid 默认使用 XFS,但是允许我们将默认配置调整为 Btrfs,来获得类似 ZFS 的对数据的保护能力。相比较 ZFS,Btrfs 更进一步减少了对于 ECC 内存的依赖,当然,如果能使用 ECC 内存,可靠性能够得到进一步提升。群晖在启用 Btrfs 作为主要的文件系统之后,曾发布过一份[白皮书](https://global.download.synology.com/download/Document/Software/WhitePaper/Firmware/DSM/All/enu/Synology_Data_Protection_White_Paper.pdf),你可以通过在白皮书中搜索“Data Protection Technologies”来了解更多的细节。 因为上篇文章中,我选择的设备不支持 ECC 内存,所以 Unraid 对于我来说就是一个不错的选择。如果你有 “ECC 焦虑”,或许翻阅文章结尾的“使用 Btrfs 来缓解数据完整性恐慌”,能够得到一些缓解。因为多数情况下,使用可靠的磁盘,搭配校验盘设计和可靠性的文件系统,配备稳定的电源保障,非 ECC 内存,也是没有问题的。 ## 安装 Unraid 最简单的 Unraid 安装方案是制作一块 USB 安装(引导)盘。正好有一块闲置很久的 16G U 盘,就它啦。这块 U 盘将在使用的过程中一直插在设备上,所以推荐选择质量 & 口碑较好的盘,如果你有靠谱的 TF 卡和读卡器,也是 OK 的。 ![找一块长期插着的 U 盘](https://attachment.soulteary.com/2023/01/21/usb-drive.jpg) 访问 [Unraid 官方网站](https://unraid.net/download),在下载界面获取适合你自己操作系统版本的 USB 安装盘制作工具。 ![Unraid USB Creator 安装盘制作工具](https://attachment.soulteary.com/2023/01/21/unraid-usb-creator.jpg) 打开工具,推荐选择默认的 “稳定版(stable)”的版本,如果你不想让工具自动从官方下载镜像,可以手动从官方下载页面提供的不同版本的系统镜像。如果你不清楚每一个版本之间的细节差异,对你的硬件来说有什么具体使用上的差异,我推荐始终选择包含了更新补丁的最新的稳定版。 ![创建引导盘](https://attachment.soulteary.com/2023/01/21/create-installer.jpg) 完成启动盘的制作后,将 U 盘插入机器,重新启动机器,将会看到熟悉的 Grub 引导界面,我们直接敲回车进入系统即可。首次安装推荐连接显示器或视频采集卡,观察是否有异常,后续正常使用则不必连接视频输出设备。 ![Unraid Grub 引导界面](https://attachment.soulteary.com/2023/01/21/grub.jpg) 在开始引导之后,界面将不停输出日志,稍等片刻,日志输出完毕的时候,“安装”的第一步就完成啦。 ![“安装”就绪](https://attachment.soulteary.com/2023/01/21/grub-ready.jpg) 访问日志中的输出的 IP 地址 “10.11.12.211”,就能够打开管理页面了,在打开的页面中完成超级管理员的用户密码设置,Unraid 的基础安装就结束啦。 ![设置系统超级管理员密码](https://attachment.soulteary.com/2023/01/21/set-user.jpg) 如果你的路由器中有 IP 绑定,或者 DHCP 设置,你可以将 Unraid 这台机器的 IP 进行固定。当然,如果你不希望使用固定 IP,也可以使用 `arp -a` 在每次使用 Unraid 设备时,先扫描一遍局域网,获取下设备的 IP 地址。 如果你在安装过程中,遇到了问题,可以参考下文中的“踩坑”部分。 ### 规划磁盘用途 在设置完超级管理员密码之后,登录系统后,我们需要对磁盘进行使用用途的规划设置。 ![规划磁盘用途](https://attachment.soulteary.com/2023/01/21/planning-disk-usage.jpg) 在上一篇文章中,我提到过我使用的磁盘,相同部分我就不再进行赘述了,来聊聊不同的地方。 1. 年末大扫除,又从家里翻出了一根因为升级而“淘汰”下来的 500GB 的 WD Blue SSD,作为缓存盘使用,Unraid 系统中缓存盘的使用不会“激活”校验盘; 2. 将之前已经插在设备上的京造 SSD 作为系统盘,存放 Unraid 运行过程中相关的程序和数据,减少主要的数据盘的唤醒和使用; 3. 原本组建 Raid 1 的两块机械磁盘中的一块,作为校验盘使用,存放系统盘和数据盘数据的校验数据。 4. 另外一块机械硬盘则负责存储真正的备份文件数据。 ![最终的硬盘规划结果](https://attachment.soulteary.com/2023/01/21/disk-list.jpg) 这样设置的好处有几个: 1. 首先,避免了机器使用过程中,全部硬盘都需要唤醒的问题,日常会优先调用固态缓存盘或者固态系统盘和机械校验盘,只有在真实写入,读取超过缓存盘缓存内存范围之后,才会启动两块机械盘。这样做既节能,又延长了主要的硬盘的使用寿命。 2. 其次,硬盘数据的可靠性进一步提升,使用 Btrfs 能够进一步保证读写数据的可靠性。 3. 最后,成本相较于双机械硬盘组 Raid 1 其实是降低的,因为校验盘可以覆盖所有磁盘的数据完整性校验的工作。 当然,这样设置也有一些缺陷,比如: 1. 单一校验盘,在极端情况下,正在写入数据的过程中,校验盘坏掉了,那么后续写入的数据的可靠性就不能够严格保证了。如果有富裕的磁盘,可以用两块磁盘作为校验盘。 2. 校验盘采用机械硬盘,一定程度影响了写入性能,毕竟写入数据都需要完成校验,才能“落地”。 3. 单一数据盘缺少冗余,只能靠外部设备、云环境备份来提升数据的安全。没办法,我的设备就这么几个硬盘位,帕累托最优就是上面的分配方案啦。 ## 配置 Unraid 系统 完成基础的安装和磁盘规划后,我们还需要做一些配置,才能够愉快的使用它来作为备份系统。 ### 使用 Unraid 作为在线备份 完成系统设置之后,默认会有一些共享配置,但是并不包含开箱即用的 Time Machine。在第一篇文章中提到,我希望这台设备能够满足我日常的在线 Time Machine 备份,所以我们需要进行一些设置。 先打开“共享”页面,能够看到系统中所有存在的共享配置。 ![网络共享界面](https://attachment.soulteary.com/2023/01/21/network-share.jpg) 点击“创建共享”按钮,打开“创建共享”的新页面。 ![创建“共享”](https://attachment.soulteary.com/2023/01/21/create-network-share.jpg) 我使用的时间机器的配置如图所示,你可以根据自己的喜好进行额外的调整。 ![设置时间机器](https://attachment.soulteary.com/2023/01/21/time-machine.jpg) 当我们配置完毕之后,我们需要在 macOS 中先连接一次这个“共享”,步骤参考图片,先访问“网络”,然后连接“Unraid”设备,最后输入账号密码,完成连接。 ![使用 macOS 连接 Unraid SMB](https://attachment.soulteary.com/2023/01/21/connect-smb.jpg) 然后在 macOS 系统中,设置时间机器的备份地址为我们创建的“共享”即可。 ![设置 macOS 的备份地址为 Unraid](https://attachment.soulteary.com/2023/01/21/set-backup.jpg) ### 完善 Unraid 上的 Docker 容器使用 Unraid 上默认的 Docker 版本只有 docker 容器,没有 `compose` 工具,为了减少 docker 应用的配置的复杂性。 我们可以从 GitHub 上下载新版本的 compose,相比较使用 Python 编写的老版本,新版本基于 Golang,干净又卫生。(如果遇到了下载问题,可以参考下文中“无法直接安装应用插件”小节来解决) ```bash wget https://github.com/docker/compose/releases/download/v2.15.1/docker-compose-linux-x86_64 wget https://github.com/docker/compose/releases/download/v2.15.1/docker-compose-linux-x86_64.sha256 ``` 完成下载之后,我们可以先对文件进行完整性校验: ```bash # shasum -c docker-compose-linux-x86_64.sha256 docker-compose-linux-x86_64: OK ``` 接着,将文件放到合适的目录,就能够在系统中使用 `docker-compose` 来进行容器的简单编排使用了: ```bash mv docker-compose-linux-x86_64 /usr/bin/docker-compose chmod +x /usr/bin/docker-compose ``` ## Unraid 踩坑经验谈 Unraid 相比较群晖缺乏相对一致的硬件支撑,相比 Windows、Ubuntu 等操作系统,缺乏大量的开发人员,所以在兼容和适配上,多多少少会有一些小的瑕疵。 不过问题不大,基本都是可解决的。 ### 踩坑:无法找到启动 U 盘 我制作安装盘的操作系统是 macOS,使用手动指定系统版本会出现引导盘不被识别的问题。但是“乖乖地”让工具下载系统,然后进行安装,则不会出现问题。(推测是制作工具逻辑处理有问题) 如果你也是手动指定版本,出现了找不到 U 盘的问题,那么试试让工具“自动”制作镜像试试。 ### 踩坑:软件没有“中文语言包” 制作启动盘时的“语言”选项仅影响启动盘制作工具的界面展示,默认的系统中是不带多语言的,只有英语一种语言。 解决问题的方法很简单,安装中文语言包即可,不过在安装过程中,你可能会遇到“无法安装” 的问题。可以参考下面的方法来解决问题。 ### 踩坑:无法直接安装“应用插件” 在 Unraid 中,我们想要安装插件,需要先启用社区插件功能(community application plugin)。 ![启用“社区应用插件”功能](https://attachment.soulteary.com/2023/01/21/install-plugins.jpg) 在启用功能的过程中,我们可能会遇到“网络失败(network failure)”的问题。 ![安装插件过程中,遭遇“网络失败”](https://attachment.soulteary.com/2023/01/21/network-failure.jpg) 这是因为 Unraid 系统的大量插件都托管于 GitHub ,虽然开通了针对中国用户的支付方式和优惠码,但是却没有针对国内提供 CDN 等解决方案。所以在下载资源的时候,会出现一些因为“网络问题”引起的麻烦。国内不少用户在[官方社区里反馈/吐槽](https://forums.unraid.net/topic/118444-%E4%BB%8E%E6%A0%B9%E6%9C%AC%E4%B8%8A%E8%A7%A3%E5%86%B3unraid%E4%BB%8Egithub%E4%B9%8B%E7%B1%BB%E7%BD%91%E7%AB%99%E4%B8%8B%E8%BD%BD%E5%8C%85%E7%BB%8F%E5%B8%B8%E5%A4%B1%E8%B4%A5%E9%97%AE%E9%A2%98/)过这个问题。 但其实,有更“简单”的方法。由于我们不会经常性的安装插件,实际使用的就那么几个罢了。**所以,我们可以通过手动执行安装命令,来完成插件的安装,而不用修改系统提供的程序。** 我们在网页中点击安装,实际上会触发下面的命令: ```bash plugin install https://raw.githubusercontent.com/Squidly271/community.applications/master/plugins/community.applications.plg nchan ``` 想要解决访问不同的问题,我们可以通过 SSH 登录 unraid 系统。在命令前添加代理服务器,再执行命令,就能够完成目标插件的安装了,比如(假设代理服务器地址为 `12.34.56.78:9000`) ```bash https_proxy=12.34.56.78:9000 plugin install https://raw.githubusercontent.com/Squidly271/community.applications/master/plugins/community.applications.plg nchan ``` 完成安装之后,刷新页面,就能够看到“社区应用市场”的界面啦。 ![能够正常使用的社区应用插件](https://attachment.soulteary.com/2023/01/21/welcome-plugin-market.jpg) 解决中文语言包的安装,和插件是类似的。默认的语言包安装命令如下: ```bash language install https://raw.githubusercontent.com/unraid/language-templates/master/limetech/lang-zh_CN.xml nchan ``` 直接执行可能也会遇到因为网络导致的无法安装的问题,调整后的命令如下: ```bash https_proxy=12.34.56.78:9000 language install https://raw.githubusercontent.com/unraid/language-templates/master/limetech/lang-zh_CN.xml nchan ``` 完整安装之后,我们在“设置”、“显示设置”、“语言”中选择语言为“简体中文”,保存设置,就能切换界面语言为熟悉的中文了。 ![设置界面语言为中文](https://attachment.soulteary.com/2023/01/21/set-lang.jpg) 至于如何获取这些命令,很简单,在网页中安装的时候,右键页面元素,在弹出菜单中选择“检查”,打开“网络调试工具”,然后再点击“安装”按钮,复制网络请求“StartCommand” 接口中的命令即可。 ![获取插件或语言包的安装命令](https://attachment.soulteary.com/2023/01/21/get-install-command.jpg) ### 踩坑:插入两块 NVMe 磁盘时,磁盘消失 原本只有一块 SSD 的时候,Unraid 启动后能够正确检测出磁盘。但是,当我插入两根 M2 SSD 之后,Unraid 磁盘界面中的 SSD “都消失”了。 观察 Unraid 自带的“工具”、“系统日志” 提供的运行日志,可以看到系统能够监测出插了两块 Nvme(M2)SSD,排除掉硬件接口故障。 ```bash Jan 14 21:20:18 Tower kernel: ahci 0000:00:17.0: Found 2 remapped NVMe devices. ``` 因为之前 Unraid 能够识别硬盘,加上排除掉硬件故障,最有可能的问题所在应该不是 Unraid 的设置,就是 BIOS 设置。在 Unraid 控制面板中“转了一圈”,没有看到针对 M2 SSD 的特别设置,那么大概率问题在 BIOS 设置。 重新启动设备,进入 BIOS 设置检查,发现 BIOS 自带了 Raid 程序,虽然并未启用这个功能,但是推测“两块”磁盘大概是因为这个功能没有禁用,导致激活了 Raid 的控制器的某些逻辑,让 Unraid 识别 NVMe SSD 失败了。 ![BIOS 自带的 Raid 程序](https://attachment.soulteary.com/2023/01/21/bios-raid.jpg) 解决方案很简单,在 BIOS 中找到 Raid 相关功能,禁用掉就好。 ![BIOS 自带的 Raid 程序](https://attachment.soulteary.com/2023/01/21/disable-bios-raid.jpg) 重新启动设备,进入 Unraid 系统,发现磁盘识别都正常啦。 ### 踩坑:NTP 服务不正常 Unraid 系统中,默认的 NTP 服务器选择的是来自 [Google 的 NTP 服务](https://developers.google.com/time)。为了避免系统在使用过程中,由于时间不正确导致的各种软件问题,我们可以对其进行调整。 可以打开“设置”,选择“时间和日期”,将 NTP 服务器设置为:“`time.apple.com`” 或者 “`time.asia.apple.com`”。 ![调整 NTP 服务器设置](https://attachment.soulteary.com/2023/01/21/ntp.jpg) ### 踩坑:调整磁盘阵列报错 当我们完成磁盘阵列设置,点击“启动”之后,不论我们想如何调整阵列,会发现 Unraid 的界面中都会提示我们“设置有误”。 某种程度上这算是 Unraid 对于系统设置的保护,解决这个问题需要先在“主界面停止磁盘阵列”,接着在工具页面选择“新配置”,重置磁盘阵列。 ![重置磁盘阵列设置](https://attachment.soulteary.com/2023/01/21/reset-disk-layout.jpg) 然后就能够和新安装的系统一样,调整配置了。 ### 踩坑:可能会丢失一次的磁盘配置 当我们购置了 Unraid 的授权之后,系统会“刷新一次”,可能会导致阵列配置失效一次。 如果出现这个问题,不要慌张,将硬盘保持原始设置重新设置一遍即可,数据不会出现损失。 ### 踩坑:官方网站无法直接使用优惠码购买 推测是官方运营策略,直接从网站购买软件授权,输入优惠码,是无法得到优惠的价格的,可能是想避免一些非渠道合作的英文区域得到折扣。 解决问题的方法很简单,在安装完系统之后,完成中文语言包的安装,调整系统语言为中文。接着,我们可以从控制面板处找到购买的链接,点击链接,在弹出的新窗口中,就能够输入优惠码,来使用折扣价格购买软件授权了。 ![购置软件授权协议](https://attachment.soulteary.com/2023/01/21/buy-license.jpg) ## 其他:使用 Btrfs 来缓解数据完整性恐慌 针对家用场景,在非 ECC 内存的环境下,使用 Btrfs 作为文件系统,可以减少很多不必要的数据完整性的恐慌问题。 **我们对于数据的完整性的恐慌,无非来自“数据存储设备”质量是否靠谱。** 涉及宿主机质量、电力保障、硬盘质量、内存质量、操作和保存数据落地的程序逻辑几方面。就家用场景来说: 1. 我们可以通过购置靠谱口碑、量产的设备来降低设备不靠谱的问题,以及通过“低时间和经济成本”,减少因为设备挂掉,服务中断所造成的麻烦。 2. 我们可以通过购置靠谱口碑、有公开测试数据报告的厂商的磁盘,以及做多份副本备份,来解决磁盘质量导致的麻烦。(不一定全部都要做在线备份,离线的磁盘也可以走起来,廉价的云服务器也是不错的选择,**但是不要做成单一选项**) 3. 我们可以通过使用考虑购置 UPS 以及将设备放在电力保障靠谱的小区(老停电的区域,住着也很麻烦不是?) 4. 选择不仅仅是维护者口碑靠谱、更有测试保障、大量验证的程序,能够减少不少麻烦的问题,当然也需要多做备份。 针对在 Btrfs 中,内存是否使用 ECC 内存,以及不使用 ECC 内存可能带来的麻烦,或许我们可以这样分析:不同类型的内存,对正确写入或读取数据可能造成什么样的问题,以及发生概率?是否可感知来进行判断。 在解答上面的问题之前,我们需要先来了解一些 Btrfs 的基础能力。 1. Btrfs 在数据的写入过程中,会计算数据校验和,然后分别存储([Btrfs 的设计](https://btrfs.wiki.kernel.org/index.php/Btrfs_design))到 Meta 元数据和 Data 文件数据(单一设备保持一份,多设备则会使用镜像元数据副本,来进一步保障数据安全),官方对于这个能力有一段[简单的介绍](https://btrfs.readthedocs.io/en/latest/Checksumming.html):“Data and metadata are checksummed by default, the checksum is calculated before write and verified after reading the blocks from devices. ” 2. Btrfs 会使用校验和来尝试自动修正数据,触发数据修正有两个时机,分别是 后台或者手动[触发 “Scrub”](https://btrfs.readthedocs.io/en/latest/Scrub.html)、以及[程序读取](https://btrfs.readthedocs.io/en/latest/Auto-repair.html)文件系统上的数据。 在了解了 Btrfs 的基础能力之后,我们来假设不使用 ECC 内存,在不同场景下可能出现的问题: 1. 在数据写入过程中,Btrfs 会计算校验和,然后将数据分别存储为 Meta 和 Data ,如果任意一份数据是坏的,会不会导致写坏的数据到磁盘中,影响数据的完整性。 2. 文件系统在更新磁盘数据的时候,如果因为硬件或操作系统导致内存中有坏数据,但是文件系统误判数据是正确的,将数据写入磁盘,影响到数据的完整性。 3. 用户在读取使用数据的时候,如果因为内存硬件或者操作系统的问题,读取了坏的数据,但是文件系统判断是正常的,从而直接将错误数据提供给用户呢? 第一点,其实官网中就有提到过,Btrfs 默认的行为是 “the checksum is calculated before write and verified after reading the blocks from devices”,文件系统不会未做校验计算,就直接往磁盘做持久化操作,写废数据。在存储过程中,如果设置 Btrfs 允许重试,数据能够修正,那么用户不会有感知。如果重试发现数据无法修正,那么将会中断写入,应用程序和用户都将会有感知。 第二点,文件系统如果在擦写(更新)数据时,经历异常遇到了脏数据,因为有校验和机制的存在,是不会将坏的数据直接写入磁盘的,和第一条其实是一样的。 第三点,经过前两点,我们知道数据落地都是有完整性保障的。 但是读取的时候,确实存在一些风险,会让我们的得到的数据不见得是正确的。其一,由于校验和自动修复机制的存在,哪怕读取的数据是有一些问题的,Btrfs 是能够一定程度上解决问题和进行修复的,但是如果所有数据副本都遇到了问题(概率低),是有可能无法保全数据的(不论是否使用 ECC)。其二,如果读取数据是正确的,但是遇到了数据需要使用内存中转,恰好中转区域因为一些问题,导致数据变脏了,这里如果应用程序没有纠错、发现能力,数据的完整性确实也是无法保障的。如果出现问题的内存区域很多,当然还有可能出现无法启动系统的问题。(如果使用 ECC 会更省心一些) **所以,如果你的硬件组合允许你使用 ECC 内存,尤其是近几年的 12 代、13 代 CPU,不放使用 ECC 内存。如果你极端恐慌这个事情的出现,可以考虑关闭“读取时自动修复”的功能,让问题更早的暴露出来。** 当然,如果你的电力靠谱,购买的硬件靠谱,没有在强磁场环境放置设备,没有 7x24x365 满负荷运行系统,触发上面问题的概率是非常低的。而且即使出现问题,如果我们使用的是经过验证的软件协议,软件也会进行数据验证和纠错,所以不必特别担心。毕竟,这个星球上有非常多的手机、电脑都使用着 non-ECC 内存,不是嘛? ## 最后 好了,这篇文章也就先写到这里啦,后续相关的文章里,我们来聊聊具体的使用。 愿我的读者和朋友们,在新的一年里,问题 “兔 few” 顺利 “兔 many”,生活 “兔 happy”。 ![图片生成自 Flag Studio](https://attachment.soulteary.com/2023/01/21/too-happy.jpg) --EOF