本文使用「署名 4.0 国际 (CC BY 4.0)」许可协议,欢迎转载、或重新修改使用,但需要注明来源。 [署名 4.0 国际 (CC BY 4.0)](https://creativecommons.org/licenses/by/4.0/deed.zh) 本文作者: 苏洋 创建时间: 2024年11月22日 统计字数: 15327字 阅读时间: 31分钟阅读 本文链接: https://soulteary.com/2024/11/22/breaking-memory-limits-a-practical-guide-to-serverization-on-the-mac-mini-m2.html ----- # 突破内存限制:Mac Mini M2 服务器化实践指南 本篇文章,我们聊聊如何使用 Mac Mini M2 来实现比上篇文章性价比更高的内存服务器使用,分享背后的一些小的思考。 希望对有类似需求的你有帮助。 ## 写在前面 在上文《[ThinkPad + Redis:构建亿级数据毫秒级查询的平民方案](https://soulteary.com/2024/11/21/thinkpad-with-redis-a-civilian-solution-for-building-millisecond-level-queries-on-billions-of-data.html)》中,我们探讨了如何用经济实惠的方案打造高性能本地服务器。然而,随着数据表查询加速需求的增加,按原方案继续扩展将占用我家中三台 64GB 内存的设备(一台运行数据库,两台负责缓存)。这无疑会挤占我其他实验环境的资源,毕竟除了家里跑着虚拟化的几台设备外,我手头可用的机器总共[也就四五台](https://soulteary.com/2024/06/10/the-worry-free-and-beautiful-homelab-device-hpe-microserver-gen10-plus-v2.html)。 ![一台崭新的旧 M2 版本的 Mac Mini](https://attachment.soulteary.com/2024/11/22/new-old-macmini-m2.jpg) 就在我为此困扰时,一个灵感突然闪现 —— 通过二手交易 App,我发现 500 米外的卖家正在出售一台被 M4 Mac Mini 替代的 M2 机型。配置完美契合需求,价格也在预算之内。半个小时后,这台设备就躺在了我的桌面上。 接下来,让我们开启全新的折腾之旅。 ## 技术方案的思考 在开始代码编写和设备配置之前,我们需要首先厘清以下四个关键问题。 ### 为什么不继续沿用原有架构 在原方案中,我们成功实现了高性价比的性能优化。然而,随着待缓存数据量的增长,我希望在**不持续增加设备投入**的前提下找到更优解。 如果仅从工程优化的角度考虑,即使我们继续深入优化当前方案,预计效率提升的空间也仅剩约10%。这个现实限制很简单:64GB 内存一旦用尽,就无法突破这个物理瓶颈。 在传统的系统架构中,当面临内存容量限制时,我们通常会考虑启用SWAP 机制来扩展存储空间。但在 Redis 环境下,这个方案却带来了严重的性能问题:一旦启用 SWAP,内存与硬盘之间的数据交换会导致访问延迟攀升至秒级,同时引发请求堵塞,最终造成服务异常。 这就给我们带来了一个颇具挑战性的思考:面对相比内存资源充裕的多的硬盘空间,是否存在一种方案,能够在保持高性能的同时,充分利用这些存储资源? ### 切换至数据持久化的 KV 系统 在上篇文章中,我们提到过一个可行方案:采用互联网公司广泛使用的、兼容 Redis 协议的持久化 KV 系统。这类系统的优势在于能够智能地处理内存与硬盘之间的数据交换,而不是等到内存耗尽才被动应对。它采用动态调度策略,在服务运行期间持续优化数据分布。 这种方案本质上是一种性能与可用性的平衡之道:虽然可能会**略微增加**单次请求的响应时间,但避免了因内存耗尽导致的服务中断或因为 SWAP 时大量数据交换产生的服务降级。其核心理念是:最小化内存与硬盘之间的数据交换,因为单次数据量交换操作越少,系统性能就越好。 至于此前提到的云端平滑迁移需求,只要我们在使用时避免采用复杂的数据结构,基于协议兼容的优势,迁移过程将变得简单直接 —— 一个迁移程序就能轻松完成这项工作。 顺着思路,让我们来看看该怎么选择硬件。 ### 方案下合适的硬件选择思路 基于前文的技术分析,我们在选择硬件时需要重点考虑三个核心要素:处理器性能、存储系统性能以及硬件可靠性。高性能的处理器能够加速内存与硬盘之间的数据交换过程,优秀的存储系统可以最小化数据迁移带来的延迟,而硬件的可靠性则确保系统能够长期稳定地承载频繁的数据交换操作。 在权衡性能需求与成本控制后,二手设备市场提供了一个极具吸引力的选择——搭载 M2 芯片的 Mac Mini。随着 M4 版本的发布,M2 Mac Mini 的二手市场价格出现了显著下跌,为我们提供了高性价比的机会。 ![Mac Mini M1 和 M2 入门版价格走势](https://attachment.soulteary.com/2024/11/22/mac-mini-price.jpg) 苹果公司在供应链管理和品质控制领域一直处于行业领先地位。虽然其原装 SSD 经常因高价格、容量限制和难以更换而备受争议。当我们通过二手市场降低硬件成本后,再结合合理的技术方案来充分利用这些高品质但容量有限的存储设备时,一个看似对普通用户不够友好的特点,反而可能成为专业应用场景下的优势。 苹果自研的 M1/M2 芯片系列在多个关键指标上都表现出色:强劲的算力、优秀的内存带宽,再加上严格的硬件品质管控。尽管这些设备没有采用传统服务器常见的 ECC 内存和 SLC 固态硬盘,但在长期高负载运行测试中,它们依然展现出极高的可靠性和耐久性,完全没有出现数据错误问题。 不过,并非所有配置的 M2 Mac Mini 都能完全满足我们的技术需求,在具体选型时还需要注意一些关键细节。 ### Mac Mini 设备的选择细节 在这个专业应用场景下,我们对硬件配置有着明确的**最低要求**:M2及以上处理器、16GB及以上内存、512GB及以上存储容量。 **512GB 容量的选择并非仅仅考虑存储空间,更重要的是性能因素。** M2 Mac Mini 搭载的 Apple SSD AP0512Z 相比 256GB 版本提供了双倍的性能表现。考虑到数据交换性能是我们方案中的关键因素,这一性能差异直接影响着系统的实际使用体验。 **选择 16GB 及以上内存**配置基于两个重要考虑:更大的内存空间能够有效减少内存与硬盘之间的数据交换频率,从而提升整体性能表现。吸取了 M1 8GB 版本的教训 —— 由于系统资源不足导致的频繁磁盘写入,曾让许多设备在一年内就严重消耗了 SSD 寿命。这种情况并非用户使用习惯导致,而是源于硬件配置限制下的系统级响应。 **处理器不建议选择 M1 版本**的原因同样有三点主要原因。技术代际有明显差距,作为 2020 年末发布的产品,其性能与 2022 年的 M2 乃至最新的 M4 相比存在明显差距。目前二手市场上主流的 M1 版本多为 8GB 内存配置,这些设备可能已经经历了大量磁盘读写操作,可靠性难以保证。而其 1900-2000 元的价格区间,性价比优势并不明显。暂时[只有 M1、M2、M2 Pro 的芯片设备支持安装 Linux 操作系统](https://asahilinux.org/fedora/),我之前在文章中《[MacBook Pro 原生安装 Ubuntu 24.04 ARM 版](https://soulteary.com/2024/05/02/macbook-pro-natively-installs-arm-ubuntu-24-04.html)》提到过,感兴趣可以自行翻阅。 如果你对 M1 和 M2 芯片的性能差异感兴趣,不妨了解以下资料:[芯片技术参数的详细对比](https://www.cpu-monkey.com/en/compare_cpu-apple_m2-vs-apple_m1)、专业论坛上的实测评测和[用户体验分享](https://www.macrumors.com/guide/m1-vs-m2-chip/)。 ## 开始实践 让我们从更换 Mac Mini 设备的操作系统开始实践。 ### 为 Mac Mini 更换操作系统 与前文相同,我依然选择了 Ubuntu(ARM 版)作为主操作系统。基础安装步骤可参照《[MacBook Pro 原生安装 Ubuntu 24.04 ARM 版](https://soulteary.com/2024/05/02/macbook-pro-natively-installs-arm-ubuntu-24-04.html)》,以下重点说明几处差异。 首先是磁盘分区方案:为新系统分配了 75% 的磁盘空间,同时预留 15% 给 macOS。这样的配置既确保了 Ubuntu 系统的充足运行空间,又保证了在需要系统维护时,macOS 能有足够空间供必要软件的安装与运行(相当于一个高级版的 PE 系统)。 ```bash We're going to resize this partition: APFS [Macintosh HD] (494.38 GB, 6 volumes) Total size: 494.38 GB Free space: 469.81 GB Available space: 431.81 GB Overhead: 0 B Minimum new size: 62.57 GB (12.66%) Enter the new size for your existing partition: You can enter a size such as '1GB', a fraction such as '50%', or the word 'min' for the smallest allowable size. Examples: 30% - 30% to macOS, 70% to the new OS 80GB - 80GB to macOS, the rest to your new OS min - Shrink macOS as much as (safely) possible » New size (50%): 15% ``` 值得一提的是,最新版安装脚本已完全兼容 Ubuntu 24.04.1。这意味着我们可以直接进行系统安装,省去了[先装早期版本再升级](https://soulteary.com/2024/05/02/macbook-pro-natively-installs-arm-ubuntu-24-04.html#%E6%9B%B4%E6%96%B0%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F)的繁琐步骤。 ```bash Choose an OS to install: 1: Ubuntu Desktop 24.04.1 LTS 2: Ubuntu Server 24.04.1 LTS 3: Ubuntu Desktop 23.10 4: Ubuntu 22.04 LTS Server (unsupported) » OS: 1 ``` 在 macOS 环境完成系统安装的第一阶段操作后,关闭设备并重新启动。在开机过程中,长按电源键直至出现引导选项界面。从中选择新安装的 Linux(Ubuntu)系统进行引导。 ![设备启动界面多了一个华丽的图标](https://attachment.soulteary.com/2024/11/22/mac-mini-boot.jpg) 首次切换至新系统时,设备会自动进入 macOS 恢复模式。此时,系统会要求输入当前主机的用户名和密码,以解锁系统并授权引导至非 macOS 系统。只需按照屏幕提示一步步操作即可完成此过程。 ![跟着安装要求照做,一路 “Next”](https://attachment.soulteary.com/2024/11/22/step2.jpg) 操作完成后,系统会自动重启并进入 Linux 环境。此时,您可能会发现显示器没有任何输出。这是因为 Linux 系统暂不支持通过雷电接口输出画面。要解决这个问题,只需将显示器连接线从雷电接口切换到 HDMI 接口即可。 ![将 DP 显示器接口切换为 HDMI](https://attachment.soulteary.com/2024/11/22/tb4-to-hdmi.jpg) Mac Mini 的 Linux 启动速度非常快。片刻之间,熟悉的 Ubuntu 界面就会在连接的显示器上出现。 ![M2 Mac Mini Ubuntu 安装完毕](https://attachment.soulteary.com/2024/11/22/mac-mini-ubuntu.jpg) 系统初始化后,首要任务是安装 SSH Server,以实现局域网内的远程管理功能。然而,在此之前,我们需要更新软件源以确保安装过程的效率和稳定性。 值得注意的是,随着系统版本的迭代,更新软件源的具体操作方法也发生了变化。 ```bash # 24.04.1 之前的版本 # sed -i 's/ports.ubuntu.com/mirrors.tuna.tsinghua.edu.cn/g' /etc/apt/sources.list # 24.04.1 及之后的版本 sed -i 's/ports.ubuntu.com/mirrors.tuna.tsinghua.edu.cn/g' /etc/apt/sources.list.d/ubuntu.sources ``` 安装过程十分简单,只需两步即可完成:首先更新软件列表(同时顺便更新系统软件),然后执行安装 `openssh-server` 的命令。 ```bash apt update && apt upgrade -y apt install openssh-server -y ``` 接下来,我们就能够在终端输入 `ssh [Mac Mini 局域网 IP 地址]` 命令,来轻松地通过 SSH 远程管理它啦。 ### 编译构建数据持久化 KV:Pika [Pika](https://github.com/OpenAtomFoundation/pika) 是一款**基于 RocksDB 存储引擎**的高性能 KV 存储系统,它不仅完全兼容 Redis 协议,还支持持久化存储和多租户特性。作为 Redis 的有力补充,它支持 string、hash、list、zset、set、geo、hyperloglog、pubsub、bitmap、stream 等所有常用的 Redis 数据结构。 日常业务过程中,当 Redis 内存使用超过特定阈值(如 16GiB)时,往往会遇到以下挑战:内存容量受限、单线程处理导致阻塞、系统启动恢复耗时过长、内存硬件成本高昂、缓冲区易达到上限、主从切换开销巨大等问题。 Pika 在保持 Redis 协议兼容性和便捷运维特性的同时,通过**持久化存储方案**解决了 Redis 面临的大数据量存储瓶颈。此外,它还支持 slaveof 主从模式,并提供全量/增量数据同步功能。 由于官方暂未提供 ARM 平台的预编译二进制文件,我们需要通过源码自行构建。构建步骤非常简单,主要命令如下: ```bash # 下载最近的正式发布版本 wget https://github.com/OpenAtomFoundation/pika/archive/refs/tags/v4.0.1.zip # 解压缩源码 unzip v4.0.1.zip # 切换工作目录 cd pika-4.0.1/ # 安装必要的构建工具 apt install cmake -y # 执行构建脚本 bash build.sh ``` 执行构建脚本后,系统首先会检查环境中是否包含所需的构建工具,随后自动下载项目的外部依赖包,并启动构建流程。在这个过程中,我们将看到类似下面的构建日志: ```bash + C_RED='\033[31m' + C_GREEN='\033[32m' + C_END='\033[0m' + CMAKE_MIN_VERSION=3.18 + TAR_MIN_VERSION=1.26 + BUILD_DIR=output + CLEAN_BUILD=false + ARGS=() + '[' '!' -f /proc/cpuinfo ']' ++ cat /proc/cpuinfo ++ grep processor ++ wc -l + CPU_CORE=8 + '[' 8 -eq 0 ']' + echo 'cpu core 8' cpu core 8 + [[ false = \t\r\u\e ]] + [[ '' = \c\l\e\a\n ]] + [[ '' = \c\o\d\i\s ]] + source ./utils/Get_OS_Version.sh ++ Get_Dist_Name ++ '[' '!' -f /etc/issue ']' ... ++ grep -Eqi Debian /etc/issue ++ grep -Eq Debian /etc/lsb-release /etc/os-release ++ grep -Eqi Ubuntu /etc/issue ++ DISTRO=Ubuntu ++ PM=apt ++ echo Ubuntu Ubuntu + check_program autoconf + type autoconf + return 0 + check_program tar + type tar ... pika PROTO_SRCS = /root/projects/pika-4.0.1/output/pika_inner_message.pb.cc;/root/projects/pika-4.0.1/output/rsync_service.pb.cc pika PROTO_HDRS = /root/projects/pika-4.0.1/output/pika_inner_message.pb.h;/root/projects/pika-4.0.1/output/rsync_service.pb.h -- Configuring done (0.1s) -- Generating done (0.0s) -- Build files have been written to: /root/projects/pika-4.0.1/output + '[' 0 -ne 0 ']' + make -j 8 [ 1%] Performing build step for 'fmt' [ 1%] Performing build step for 'gflags' [ 3%] Built target unwind [ 3%] Performing build step for 'gtest' [ 3%] Performing build step for 'zlib' [ 6%] Performing build step for 'lz4' [ 6%] Performing build step for 'snappy' [ 7%] Performing build step for 'zstd' [ 8%] Performing build step for 'jemalloc' ... [100%] Linking CXX executable pika [100%] Built target pika [100%] Linking CXX executable keys_test [100%] Built target keys_test [100%] Linking CXX executable zsets_test [100%] Built target zsets_test + '[' 0 -eq 0 ']' + echo -e 'pika compile complete, output file \033[32m output/pika \033[0m' pika compile complete, output file output/pika ``` 当出现 `pika compile complete, output file output/pika` 提示时,表明程序构建已成功完成。 编译过程中,Mac Mini 的功耗首次攀升至 26 瓦,令人惊讶。而在日常运行时,功耗却始终保持在 1 至 5 瓦之间,如此低的数值甚至让我一度怀疑电源显示器是否出现故障。 ![M2 Mac Mini 编译峰值功耗](https://attachment.soulteary.com/2024/11/22/power.jpg) ### 基础功能验证 接下来,我们可以通过以下命令对 Pika 进行基础功能验证(**使用少量内存和大量磁盘提供等效 Redis 的服务**): ```bash ./output/pika -c ./conf/pika.conf ``` 运行命令后,终端将显示 Pika 在默认配置下的运行日志。 ```bash ... I20241122 15:02:55.769603] 78 cache-type string, set, zset, list, hash, bit I20241122 15:02:55.769608] 79 zset-cache-field-num-per-key 512 I20241122 15:02:55.769613] 80 zset-cache-start-direction 0 I20241122 15:02:55.769618] 81 cache-maxmemory 10737418240 I20241122 15:02:55.769622] 82 cache-maxmemory-policy 1 I20241122 15:02:55.769627] 83 cache-maxmemory-samples 5 I20241122 15:02:55.769632] 84 cache-lfu-decay-time 1 I20241122 15:02:55.769637] 85 internal-used-unfinished-full-sync I20241122 15:02:55.769641] 86 wash-data true ............. .... ..... ..... ..... ################# #### ##### ##### ####### #### ##### #### ##### ##### ######### #### ##### #### ##### ##### #### ##### #### ##### #### ##### ##### #### ##### ################ #### ##### ##### #### ##### #### #### ##### ##### ################# #### #### ##### ###### ##### ##### #### #### ##### ###### ##### ##### -----------Pika config end---------- W20241122 15:02:55.769673 52462 pika.cc:191] your 'limit -n ' of 1024 is not enough for Redis to start. pika have successfully reconfig it to 25000 I20241122 15:02:55.769685 52462 pika.cc:209] Server at: ./conf/pika.conf I20241122 15:02:55.769832 52462 net_interfaces.cc:108] Using Networker Interface: end0 I20241122 15:02:55.769907 52462 net_interfaces.cc:152] got ip 10.11.12.93 I20241122 15:02:55.769915 52462 pika_server.cc:157] host: 10.11.12.93 port: 9221 I20241122 15:02:55.769927 52462 pika_server.cc:71] Worker queue limit is 20100 W20241122 15:02:55.769932 52462 pika_server.cc:72] 0.0.0.0 I20241122 15:02:55.770182 52462 pika_server.cc:1664] Dump file is not exist,path: ./dump/ I20241122 15:02:55.770282 52462 pika_binlog.cc:98] Binlog: Find the exist file. I20241122 15:02:55.797559 52462 pika_db.cc:50] db0 DB Success I20241122 15:02:55.797613 52783 pika_cache_load_thread.cc:181] PikaCacheLoadThread::ThreadMain Start I20241122 15:02:55.798816 52462 net_util.cc:121] TimerTaskThread Starting... I20241122 15:02:55.798950 52462 pika_server.cc:214] Pika Server going to start I20241122 15:02:55.798961 52462 rsync_server.cc:48] start RsyncServer ... I20241122 15:02:55.799070 52462 rsync_server.cc:60] RsyncServer started ... ``` 在默认配置下,Pika 运行于 9222 端口,并为 RocksDB 的数据设置了如下策略: - 数据生命周期为 7 天 - 每三天自动执行一次数据压缩和过期清理 为避免数据因自动清理而丢失,我们需要根据实际应用场景调整这些配置,特别是延长数据的生命周期。 ### 测试验证 M2 Mac Mini 上的 Pika 性能 ![M2 Mac Mini 内存数据库性能测试](https://attachment.soulteary.com/2024/11/22/benchmark.jpg) 测试结果令我非常满意。这台设备不仅能耗极低、运行静音,还几乎跑满了设备本身的千兆网口,同时保留了充足的系统算力。 测试环境配置: - 网络环境:基于《[千兆之上:家庭网络 2.5G 升级实践](https://soulteary.com/2024/11/19/beyond-gigabit-home-network-2-5g-upgrade-practice.html)》搭建的 2.5G 内网 - 服务端:Mac Mini M2(千兆网口,未安装 2.5G 网卡) - 测试端:MacBook Air M3 本次测试采用开源工具 [Vire Benchmark](https://github.com/vipshop/vire/blob/master/tests/vrt_benchmark.c)。测试流程如下: - 通过 Docker 拉取预构建镜像 - 启动容器 - 执行性能测试:模拟 100 并发,向 Pika 发送 10 万次请求,测试 `PING`、`SET`、`GET` 命令,每次请求携带 20KB 数据。 具体测试命令如下: ```bash docker pull putianhui/vire-benchmark docker run --rm -it putianhui/vire-benchmark bash vire-benchmark -h 10.11.12.93 -p 9221 -t ping,set,get -n 100000 -c 100 -d 20480 ``` 执行完成后,系统将返回如下测试结果: ```bash ====== PING_INLINE ====== 100000 requests completed in 2.35 seconds 100 parallel clients 20480 bytes payload keep alive: 1 16.49% <= 1 milliseconds 59.89% <= 2 milliseconds 92.06% <= 3 milliseconds 96.72% <= 4 milliseconds 97.89% <= 5 milliseconds 98.40% <= 6 milliseconds 98.70% <= 7 milliseconds 98.93% <= 8 milliseconds 99.00% <= 9 milliseconds 99.07% <= 10 milliseconds 99.08% <= 11 milliseconds 99.22% <= 12 milliseconds 99.27% <= 13 milliseconds 99.30% <= 14 milliseconds 99.31% <= 15 milliseconds 99.31% <= 16 milliseconds 99.33% <= 17 milliseconds 99.35% <= 18 milliseconds 99.40% <= 19 milliseconds 99.43% <= 20 milliseconds 99.48% <= 21 milliseconds 99.58% <= 22 milliseconds 99.63% <= 23 milliseconds 99.79% <= 24 milliseconds 99.82% <= 25 milliseconds 99.84% <= 26 milliseconds 99.84% <= 35 milliseconds 99.84% <= 36 milliseconds 99.85% <= 39 milliseconds 99.85% <= 40 milliseconds 99.85% <= 41 milliseconds 99.86% <= 42 milliseconds 99.87% <= 43 milliseconds 99.87% <= 44 milliseconds 99.88% <= 45 milliseconds 99.91% <= 46 milliseconds 99.95% <= 47 milliseconds 99.97% <= 48 milliseconds 99.98% <= 49 milliseconds 100.00% <= 50 milliseconds 100.00% <= 51 milliseconds 100.00% <= 52 milliseconds 100.00% <= 53 milliseconds 42607.59 requests per second ====== PING_BULK ====== 100000 requests completed in 1.98 seconds 100 parallel clients 20480 bytes payload keep alive: 1 12.37% <= 1 milliseconds 79.92% <= 2 milliseconds 93.37% <= 3 milliseconds 96.13% <= 4 milliseconds 97.54% <= 5 milliseconds 98.19% <= 6 milliseconds 98.58% <= 7 milliseconds 98.84% <= 8 milliseconds 99.04% <= 9 milliseconds 99.25% <= 10 milliseconds 99.35% <= 11 milliseconds 99.44% <= 12 milliseconds 99.53% <= 13 milliseconds 99.59% <= 14 milliseconds 99.65% <= 15 milliseconds 99.71% <= 16 milliseconds 99.73% <= 17 milliseconds 99.79% <= 18 milliseconds 99.84% <= 19 milliseconds 99.86% <= 20 milliseconds 99.88% <= 55 milliseconds 99.89% <= 56 milliseconds 99.89% <= 57 milliseconds 99.90% <= 58 milliseconds 99.90% <= 59 milliseconds 99.91% <= 60 milliseconds 99.91% <= 61 milliseconds 99.93% <= 62 milliseconds 99.93% <= 63 milliseconds 99.94% <= 64 milliseconds 99.96% <= 65 milliseconds 99.97% <= 67 milliseconds 99.97% <= 68 milliseconds 99.98% <= 103 milliseconds 99.98% <= 104 milliseconds 99.99% <= 108 milliseconds 100.00% <= 112 milliseconds 100.00% <= 113 milliseconds 100.00% <= 113 milliseconds 50632.91 requests per second ``` 性能评估采用了 Redis 基准测试的两种标准方法:Redis Inline 格式和 Redis Bulk 批量格式。无论使用哪种方式,系统性能均大幅超越预期,完全满足并超出了我们的业务需求。 ## 其他 在前文的“技术方案思考”小节中,我曾提及了选择 Mac Mini 作为设备的考量。既然设备已经到手,自然要一探究竟。 ![重新擦除设备系统后,查看系统情况概览](https://attachment.soulteary.com/2024/11/22/about-macmini.jpg) 首先,让我们来看看这台二手 Mac Mini 的硬盘使用情况。拿到设备后,我立即进行了一次简单而关键的磁盘信息读取: ```bash # smartctl -x /dev/disk0s1 smartctl 7.4 2023-08-01 r5530 [Darwin 24.0.0 arm64] (local build) Copyright (C) 2002-23, Bruce Allen, Christian Franke, www.smartmontools.org === START OF INFORMATION SECTION === Model Number: APPLE SSD AP0512Z Serial Number: 0ba01ee32330982c Firmware Version: 499.0.9 PCI Vendor/Subsystem ID: 0x106b IEEE OUI Identifier: 0x000000 Controller ID: 0 NVMe Version: <1.2 Number of Namespaces: 3 Local Time is: Thu Nov 21 06:06:19 2024 PST Firmware Updates (0x02): 1 Slot Optional Admin Commands (0x0004): Frmw_DL Optional NVM Commands (0x0004): DS_Mngmt Maximum Data Transfer Size: 256 Pages Supported Power States St Op Max Active Idle RL RT WL WT Ent_Lat Ex_Lat 0 + 0.00W - - 0 0 0 0 0 0 === START OF SMART DATA SECTION === SMART overall-health self-assessment test result: PASSED SMART/Health Information (NVMe Log 0x02) Critical Warning: 0x00 Temperature: 31 Celsius Available Spare: 100% Available Spare Threshold: 99% Percentage Used: 0% Data Units Read: 33,153,911 [16.9 TB] Data Units Written: 10,289,877 [5.26 TB] Host Read Commands: 522,484,819 Host Write Commands: 227,748,421 Controller Busy Time: 0 Power Cycles: 450 Power On Hours: 177 Unsafe Shutdowns: 16 Media and Data Integrity Errors: 0 Error Information Log Entries: 0 Read 1 entries from Error Information Log failed: GetLogPage failed: system=0x38, sub=0x0, code=745 ``` 这台 Mac Mini 的使用数据表明设备**处于近乎全新**的状态。首先,SSD 硬盘的可用备用空间仍保持在 100%,表明设备几乎未被使用过。在读写方面,总读取量达到 16.9 TB,写入量为 5.26 TB,读取命令约 5.22 亿次,写入命令 2.28 亿次,形成了 3.2:1 的读写比例。这一比例说明设备的主要活动集中在内存中,使用强度相对较轻。 尽管设备记录了 450 次开关机循环(可能包括休眠唤醒),但实际通电时间仅有 177 小时,约合 7.4 天。这一数据进一步证实了设备的轻度使用状态。设备使用过程中的唯一异常是,硬盘记录了 16 次强制关机或断电操作。 综上所述,虽然这台 Mac Mini 经历了一定次数的开关机,但其实际使用时间极短,硬盘几乎未被使用。 当然,最重要的还是实际使用性能。我在这台 Mac Mini 上编译了上一篇文章中的内存读写性能测试工具,并进行了三轮测试。 ```bash # gcc -O2 memtest.c -o memtest # ./memtest 校验结果: 25427968 写入能力: 8.54 GB/s 读取能力: 298.51 GB/s # ./memtest 校验结果: 25427968 写入能力: 9.21 GB/s 读取能力: 286.46 GB/s # ./memtest 校验结果: 25427968 写入能力: 9.19 GB/s 读取能力: 293.86 GB/s ``` 尽管在读取性能上略显逊色,只有 ThinkPad 方案的 60%,但这台 Mac Mini 在写入速度超过 ThinkPad 接近 5 倍。 文章至此已近尾声,让我与各位喜欢折腾的朋友分享一下这次设备购入的成本和设备市场价格情况。 ![文章相关的设备二手市场价格](https://attachment.soulteary.com/2024/11/22/market.jpg) 由于这台设备距离我近在咫尺,当晚(九点)即可验证方案可行性,我选择了以二手市场中较高的价格成交。考虑到设备几乎全新,且目前仅此类设备支持安装 Linux,这个价格或许仍算合理:平摊到五年,每年 700 元(云服务器等规格一个月 1200 元起)。 当然,若您不急于使用,耐心等待总能换来更优惠的价格。特别是随着 M4 芯片 Mac Mini 的普及,相信这类设备的价格必将进一步下探。 ## 最后 至此,本次探索告一段落。等这段手头事情忙完后,我计划折腾一套集群方案。 当然,正如本次实践,期待合适的老款 Mac Mini M2 能回归理想价位。目前的设备价格略显偏高,尤其考虑到折扣后的 M4 版 Mac Mini 仅需 3500 元。 ![:D](https://attachment.soulteary.com/2024/11/22/bye.jpg) 祝大家玩的开心。 --EOF