# 构建家用NAS过程中的碎碎念

## 前言

最近存储告急，要给自己的数据找个家，所以开始琢磨NAS的事情，购买，搭建NAS的时候，阅读了很多资料，也发现了不少坑，留在这里，给大家参考。 本文可以看作一个组建自宅或者小型企业使用NAS的入门手册，很多措施或因地制宜、或需要有效利用已有的电子产品，稳定性也并非最优，因此并不适用较大规模的商业场景。

## NAS是？

网络附加存储（英语：Network Attached Storage，缩写：NAS），粗略的说，就是可以网络访问的一个硬盘。如果你没有概念，可以先阅读一下Wiki：[NAS 维基百科](https://zh.wikipedia.org/wiki/%E7%B6%B2%E8%B7%AF%E9%99%84%E5%8A%A0%E5%84%B2%E5%AD%98)，如果你没法翻墙，可以阅读：[NAS 百度百科](https://baike.baidu.com/item/NAS/3465615)。

在我来看，NAS就是一台电脑，只是这台电脑装着比别的电脑多得多的硬盘，并且利用厂商开发的特殊软件完成一些特殊功能。对于一个工程师来说，用旧电脑（台式机，可容纳多块硬盘才行）DIY一个NAS可能更加便宜和可玩，我手头没有这样的旧电脑，也忙于其它事情不愿花几周去折腾（其实折腾过了），所以就买了一台NAS。

## 你是不是需要NAS？

### 从数据量和性质上考虑

那么你是否需要NAS呢？如果：

1. 你有大量（我的理解是超过300G）的静态数据（也就是写入后只是读取不需要修改的数据）需要可靠存储，可以选用NAS。
2. 如果你有大量（我的理解是超过10G）的动态数据（也就是随时需要修改的数据）需要可靠存储，可以选用NAS。
3. 不要求可靠存储，但是数据量大于8TB的。

下面是我写的一张家用数据备份的选型表，仅代表个人意见。而且各家的数据不一样，往往是混合起来使用。

| 是否需要可靠存储 | 数据类型  | 数据量    | 应该选择               |
| -------- | ----- | ------ | ------------------ |
| 否        | 动态/静态 | <8TB   | 电脑硬盘或者移动硬盘         |
| 否        | 动态/静态 | >8TB   | 可以考虑NAS（RAID0）     |
| 是        | 动态/静态 | <10GB  | Google Cloud 之类的网盘 |
| 是        | 静态    | <300GB | 移动硬盘或者蓝光碟          |
| 是        | 动态    | >10GB  | 可以考虑NAS（不能用RAID0）  |
| 是        | 静态    | >8TB   | 可以考虑NAS（不能用RAID0）  |

如果你不需要可靠存储，或者数据量不够，NAS则未必必要。对于需要可靠存储的情况：如果你的静态数据少于300GB，那么使用移动硬盘+刻录蓝光碟备份是比较好的选择，如果你的动态数据少于10G，那么可以选用GoogleDrive或者OneDrive这样的网盘来的更加轻松，也可以在主机内用两个硬盘分区组建RAID存储。 再或者，你根本不需要可靠存储，数据丢了问题也不大，那么买一个大一点的移动硬盘或者电脑内置硬盘是比较好的选择。

### 从可访问性上考虑

举个典型的例子：如果你是个小工作室，大家分散办公，且需要剪辑视频公用一些素材，那么可以选用NAS。但是NAS不是必要的，一个略有经验的工程师同样可以用电脑搭建起来同样的东西，如果你对网络没什么概念，那么NAS可能是最好的选择了。

## NAS的购买

我们这里不考虑买到假货的问题（一般不会，因为厂商有专属软件），着重说一下NAS购买时需要注意的问题。 我也会说一下我自己的选择：QNAP TS-451D2（4GB）+自己又买了一块4GB内存 + 西部数据NAS红盘（8TB），但是我的选择未必适合你，请耐心读完自己选择。

### NAS本身

在购买NAS本身的时候，首先要看硬件，最重要的是以下几点：

* 可容纳硬盘的数量
* 网卡的速度
* CPU的指令集

可容纳硬盘的数量决定了你的存储能力的上限，也决定了你能做怎样的RAID（下文慢慢说），以及是否有空余的槽位用SSD做访问加速。如果你要可靠存储的话，槽位千万不能小于2个，否则无法组建RAID1。 我自己购买的是4个槽位（SLOT）的NAS。 网卡的速度决定了你的访问速度，一般来说，千兆网卡已经是标配了，一般不需要关心，对于有线布线连接困难的场景，你可能需要选用带无线功能的NAS，或者确认一下是否可以用外接无线网卡解决。 CPU的指令集一般是不太被关心的内容，但是如果你需要在NAS上运行一下自己的程序，或者NAS支持容器化，那最好选择AMD64指令集的NAS。

厂商的话，一般也就是群晖，QNAP，IO-DATA之类。搜索NAS大多可以搜到这些厂商，这里就不做推荐了。我自己的话，最后选了QNAP。

既然是电脑，当然也可以改造台式机，甚至自己购买刀片服务器，但是我在网上很难找到某种台式机究竟支持多少硬盘的槽位的数据，所以干脆买了专用NAS。

### 硬盘（HDD）

机械硬盘便宜，存储空间大，是NAS的首选。但是NAS的话，最好选用NAS的专用磁盘，比如希捷的铁狼或者WD的红盘之类，NAS盘和其它盘的不同之处在于磁盘的控制器会主动向系统报告磁盘错误，而不是卡住不动。长时间卡住不动的硬盘会被NAS认为是坏盘而踢下线报错。考虑到硬盘其实没那么容易坏（~~其实一摔就坏~~），所以你用非专门为NAS设计的硬盘也不是不可接受。

容量你自己肯定会考虑，除了是否专用NAS的控制器以外，最重要的一个概念是SMR与CMR。简单来说，成本大致一样的情况下，SMR通过牺牲了读写速度换取更大的容量。

也可以说，同样容量下，SMR成本低速度慢。如果是组RAID1的话，对随机读写性能要求更高，SMR就更慢了。（事实上，SMR不仅速度慢，而且不靠谱，数据相当容易丢）。 比起希捷的故障率，WD（西部数据）的NAS红盘系列一直是“靠谱”的象征，直到有一天，有人发现WD的部分容量的NAS红盘居然用SMR技术，并且因此造成自己数据损坏。 于是乎被群众吊起来暴打，被希捷嘲讽，打到后来西数慌了，网上公布了所有SMR型号的硬盘（但是不全面，比如绿盘就没人说得清楚，但是估计有SMR）。 用NAS的人一定对数据也是比较重视的，大多会也组RAID1，所以WD的NAS系列红盘用SMR真的是杀人诛心啊。

企业知不知道自己的盘垃圾呢？当然知道，CMR的盘一般能保3年，SMR的盘一般只保1年。作为消费者怎么识别SMR呢？很简单，我只看购买页面+官网查询型号，没有说是CMR的一律认定为SMR，宁可错杀不要放过。

那么SMR就真的一无是处吗？也不是，SMR比CMR环保，且SMR比CMR要便宜，从成本的角度出发，可以买一块放不重要的毛片儿啊电影啊之类的数据。如果不是经常读写的静态数据，也可以用来组RAID1保证可靠性，也可以降低成本。但是如果成本不是那么敏感的话，我还是不建议在NAS中使用任何SMR盘的。

虽然希捷很良心的不在NAS盘里用SMR，但是故障率仍然比西部数据的高，所以我最后还是选择了西部数据的NAS红盘，并在购买前确认该型号是CMR。

#### 对IO-DATA的批判

这里需要批判一下IO-DATA，我本来看上了一款IO-DATA的家用NAS，除了硬盘的拆换不是很方便，以及用的CPU是ARM架构而不是AMD64以外没什么问题。 问题就出在内置的硬盘上，内置的硬盘有两个问题：价格相当黑心，以及用盘相当不专业。

IO-DATA这款机器在Amazon上裸机的价格是不到25000日元左右，16TB（2x8TB）版本的价格是112800日元，换句话说，折合每块8TB盘的价格是43900日元。 如果用这个价格去买8TB的NAS红盘（CMR），价格是20000日元左右，4W+日元的价格我完全可以买最贵的金盘系列了。

但是IO-DATA内置的到底是什么盘呢？很难找的一个宣传画册上的官方照片显示是绿盘，我之前在实体店探查过是似乎某种SMR盘。这就是让用户花最贵的钱，买最差的盘。 我去实体店看过包装，包装上的小字写了盘的型号（我应该没记错），更鸡贼的是IO-DATA的官网页面，官网上不放包装的高清大图。 因为高清大图可以看清小字，为了不让你看清楚小字，所以官网一律是640\*480的图。

更更鸡贼的是：如果你去IO-DATA的替换配件售卖区，那里卖的盘基本都是CMR的好盘，比如WD的红盘，只有内置在机器中的盘是绿盘。

### 硬盘（SSD）

即使最便宜的SSD，存储成本也是HDD的4倍左右，所以一般是不选用的。

不过SSD贵在速度快，所以有的NAS（比如QNAP的Qtier技术）会支持SSD和HDD共同组成存储池，数据尽量存在SSD里面，随后将用不到的数据挪到HDD里面，这样可以在日常使用里大致获得SSD的性能和HDD的成本。类似Apple的Fusion硬盘技术。

说到SSD的选购，其实是个很深的大坑，影响一个SSD最终性能的是主控，缓存和颗粒共同决定的：

1. 主控的话花样比较少，只是有好坏快慢之分，垃圾回收算法先进落后之别。
2. 缓存的话有两层意思
   * 一层是用内存（DRAM）颗粒加速访问，这里花样也比较少，
   * 另一层是颗粒“降级”，比如明明是QLC或者TLC，但是当成SLC用，颗粒容量暂时减到几分之一但是速度就能大幅提升，等到写入数据超过这部分再启用TLC或者QLC，这个时候写入就慢了。所以在测试的时候，可能会出现开始写入速度很快，但是写入了几分之一的容量后开始掉速的情况。
3. 颗粒的花样就多了：
   * SLC/MLC/TLC/QLC，指的是一个单元（Cell）存储1/2/3/4Bit的信息，也就是把电压分为2/4/8/16份。随着信息量增大，可读写次数（寿命）下降，速度也相应的变慢。这里多说一句，虽然寿命下降，但是正常使用的话一般能比电脑都活的久……
   * 原片/白片/黑片：你可以理解为可靠性逐层递减，白片的意思是，原厂最严格的测试不合格，但是能用，所以不打标签出售给二线小厂用。黑片就是残次品，一般会在颗粒上划线表明报废，一些黑心厂商会用，比如金泰克七彩虹之类。
   * 批次：颗粒是需要调校的，准确的说调整的不是颗粒是主控。如果不是同一个批次，调校就无从谈起，就会有性能和稳定性的问题。

这里列出一些SSD厂商的黑料：

厂商宣传自己的SSD的时候很多都宣传“最高读写速度可达”，这里的读写速度往往是降级读写速度，一旦写入达到一定容量，速度就立刻掉下来了。 还有一些厂商会针对测试软件做优化，监测到写入测试数据的时候，实际不写入硬盘，导致看上去性能爆炸。 以及这个参考材料：[这些硬盘不要买！2020那些不推荐的固态硬盘](https://zhuanlan.zhihu.com/p/166162142) [「存档链接」](https://archive.vn/hSDBR)

* 大唐 SSD 虚假宣传，将使用QLC颗粒的固态宣传成TLC
* 长芯 SSD 虚假宣传，将使用QLC颗粒的固态宣传成TLC，还把低端入门主控宣传为高端主控
* 海康威视 SSD 主控降级虚假宣传，颗粒黑片回收片混用，QLC冒充TLC，曾被认为是国产固态之光，后来发现和上面都是一路货色。
* ……

总而言之，如果你需要对常用文件进行访问加速，那么可以选一块不大的（比如100G左右）的，性能较好的SSD，组成Qtier存储池。

对于使用电脑DIY NAS的朋友，我推荐这个项目：[Open Cache Acceleration Software](https://open-cas.github.io/) 相信会有所帮助。

## NAS的搭建和管理

### 关于RAID

如果你不知道RAID是什么，可以先阅读[维基百科 RAID](https://zh.wikipedia.org/zh-cn/RAID)。 简而言之，你需要可靠存储的时候，可以组建RAID1，这里我不是很推荐RAID5或者RAID6，随机读写的性能并不好（MongoDB就推荐用户不要用RAID5/6，参考[这个文档](https://docs.mongodb.com/manual/administration/production-notes/index.html#raid)），更重要的是，一旦硬盘失效，重建的成功率太低了。

我的话组建了一个2个8TB磁盘的RAID1，这样就有了8TB可靠的存储空间。之所以可靠存储要靠RAID，还得从机械硬盘的失效说起。 硬盘的失效，往往难以预测，大多数的厂商都说自己有算法可以根据S.M.A.R.T.参数预测失效，但是实际上，预测并不容易。（如果你想详细了解S.M.A.R.T.，可以看[这个Wiki](https://zh.wikipedia.org/zh-hans/S.M.A.R.T.)）。

曾有云存储的厂商做过统计，这里是一篇2014年的Blog，在4万块硬盘存储100PB的数据上的研究表明，SMART的5，187，188，197，198参数对失效预测有用：[Hard Drive SMART Stats](https://www.backblaze.com/blog/hard-drive-smart-stats/)

既然我们难以预测失效，那么我们不如随时备份数据，这就是RAID的作用。 需要说明的是，SSD没有HDD的这个问题，只是单纯的贵而已……所以SSD组RAID的需求就不那么迫切。

如果你是用自己的主机搭建RAID，除了买专用硬件以外，也可以试试软件RAID，详细请参照这个Blog：[Linux下利用mdadm设置软件 RAID](https://blog.tsingjyujing.com/other-tech/mdadm)

### 网络文件协议

一般的网络文件协议有SMB/NFS/FTP/AFP（苹果才用）/...。如果你只是简单的存取普通文件，那么SMB就可以了，如果你在Linux上，希望某些应用程序的数据放到NAS上，那你最好用NFS的方式挂载，SMB（或者说CIFS）不支持诸如软链接之类的东西。

但是SMB的好处是简单易用，带较好的权限控制，NFSv4协议的话按说是有ACL的，但是很多厂商没有实现（可能是出于兼容考虑），挂载也是使用IP地址在做验证，所以安全性不如SMB协议。

Linux上的话，NFS我就不介绍了，SMB协议可以用Samba软件实现。

### 特殊存储协议

广义的说，兼容Amazon S3接口的存储程序，比如Minio或者SeaweedFS，乃至MySQL或者MongoDB这种数据库也算是网络存储。

比如我希望存储一些非结构化的数据，所用了容器启动MongoDB。 这个主要是针对程序员群体的，可能会需要Amazon S3兼容存储。

其实有好几种方式提供S3兼容的存储，我买的NAS可以安装厂商开发的一个叫QuObject的程序，可以让文件系统兼容S3或者Swift的接口。也可以用容器技术启动Minio或者SeaweedFS（当然还有很多其它开源的S3存储选择）。 但是我最后选的是SeaweedFS，因为我的小文件太多了，其它两种方式固然方便——指的是直接访问文件系统的时候可以直接看到目录结构，但是小文件的存储无论对与NAS还是普通电脑的文件系统都是一个灾难。 不过有一点好的是，其实QNAP已经提供了Volume这个东西，所以就算很多小文件，备份起来并不是那么痛苦。 不过我的SeaweedFS在这里真的是牛刀杀鸡，SeaweedFS是可以支撑集群乃至多地存储的系统。

如果你需要这些协议或者功能，这里我推荐能够运行Docker Container的NAS，如果你主要依赖S3协议或者数据库，我更推荐你自己用电脑搭建，因为这个时候，你的主要访问需求并不是文件了，而主要的负载也不再是IO而很有可能还有大量计算，NAS的CPU一般都比较孱弱，往往特殊设计的硬件加速，所以这个时候自建可能更好。

### 网络

这一节主要给需要远程访问数据的人。

在之前的文章：[为什么我劝你不要使用云计算？](https://blog.tsingjyujing.com/other-tech/cloud-or-not) 里面，我详细介绍过如果家里有公网IP，可以完全不用云服务自己搭建，或者干脆使用内网穿透，这里也是同理。就算你自己没有公网IP，厂商一般也会提供远程访问的方案，但是这样相当于数据要从厂商的网络上经过，有泄漏的风险，所以厂商一般也会提醒不要用这种方式传输机密数据。

同时需要注意的风险是，比如为了配合监管，[群晖 NAS 用户须在年底前绑定手机号，否则将 “断网”](https://www.ithome.com/0/514/611.htm)。所以之后如果为了配合监管，对经过厂商网络传输的数据进行审查也不是没有可能，请务必注意（不过目前看不太可能把审查下沉到个人机器里，我大胆的推测，并不是审查者不想做这样的事情，而是不论数据量还是计算量都不可行）。

除了这种方式，还可以用[ZeroTier](https://www.zerotier.com/)来组建跨区域的局域网，我自己目前用的也是这种方式，当然我同时也有公网IP，但是局域网的方式要更加安全。

## 总结

本文主要介绍NAS以及其附件选购的时候要注意的点，以及一些网络服务的搭建。看完文章你应该明白什么时候需要NAS，需要什么样的NAS，需要什么样的硬盘。

如果有错漏之处，或者新的内容，欢迎联系我。

## 附录

### 一些 Docker Compose 配置

#### MongoDB

```yaml
version: "3"
services:
  db:
    image: "mongo:4"
    restart: always
    environment:
      MONGO_INITDB_ROOT_USERNAME: <your own username>
      MONGO_INITDB_ROOT_PASSWORD: <your own password>
    command: "--wiredTigerCacheSizeGB 1.0 --auth" # Modify the memory by your hardware condition
    ports:
      - 27017:27017
    volumes:
      # You should change your own path or use docker volume here
      - /share/Container/data/mongo/db:/data/db
      - /share/Container/data/mongo/configdb:/data/configdb
```

#### SeaweedFS

```yaml
version: "3"
services:
  app:
    image: "chrislusf/seaweedfs"
    command:
      - server
      - -dir=/data/data # Should create dir manually before start
      - -s3
      - -s3.config=/data/s3.json # Define user and authorization in this file
      - -s3.port=8333
      - -filer
      - -filer.dirListLimit=50000
      - -master.volumeSizeLimitMB=4000 # ~4GB per file
      - -volume.max=1000 # 1000 * ~4GB = ~4TB in max
      - -volume.index=leveldb # You can remove this line if you'd like to put index data in memory
    ports:
      - 8333:8333
    volumes:
      # You should change your own path
      - /share/Container/data/weedfs/:/data
```

#### Node Exporter

```yaml
version: '3'
services:
  node_exporter:
    image: quay.io/prometheus/node-exporter
    restart: always
    pid: "host"
    command: ["--path.rootfs=/host"]
    volumes:
      - "/:/host:ro,rslave"
    ports:
      - "9100:9100"
```
