突破内存限制:Mac Mini M2 服务器化实践指南

本篇文章,我们聊聊如何使用 Mac Mini M2 来实现比上篇文章性价比更高的内存服务器使用,分享背后的一些小的思考。

希望对有类似需求的你有帮助。

写在前面

在上文《ThinkPad + Redis:构建亿级数据毫秒级查询的平民方案》中,我们探讨了如何用经济实惠的方案打造高性能本地服务器。然而,随着数据表查询加速需求的增加,按原方案继续扩展将占用我家中三台 64GB 内存的设备(一台运行数据库,两台负责缓存)。这无疑会挤占我其他实验环境的资源,毕竟除了家里跑着虚拟化的几台设备外,我手头可用的机器总共也就四五台。

一台崭新的旧 M2 版本的 Mac Mini

就在我为此困扰时,一个灵感突然闪现 —— 通过二手交易 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 入门版价格走势

苹果公司在供应链管理和品质控制领域一直处于行业领先地位。虽然其原装 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 操作系统,我之前在文章中《MacBook Pro 原生安装 Ubuntu 24.04 ARM 版》提到过,感兴趣可以自行翻阅。

如果你对 M1 和 M2 芯片的性能差异感兴趣,不妨了解以下资料:芯片技术参数的详细对比、专业论坛上的实测评测和用户体验分享。

开始实践

让我们从更换 Mac Mini 设备的操作系统开始实践。

为 Mac Mini 更换操作系统

与前文相同,我依然选择了 Ubuntu(ARM 版)作为主操作系统。基础安装步骤可参照《MacBook Pro 原生安装 Ubuntu 24.04 ARM 版》,以下重点说明几处差异。

首先是磁盘分区方案:为新系统分配了 75% 的磁盘空间,同时预留 15% 给 macOS。这样的配置既确保了 Ubuntu 系统的充足运行空间,又保证了在需要系统维护时,macOS 能有足够空间供必要软件的安装与运行(相当于一个高级版的 PE 系统)。

We're going to resize this partition:APFS [Macintosh HD] (494.38 GB, 6 volumes)Total size: 494.38 GBFree space: 469.81 GBAvailable space: 431.81 GBOverhead: 0 BMinimum 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 OS80GB - 80GB to macOS, the rest to your new OSmin  - Shrink macOS as much as (safely) possible» New size (50%): 15%

值得一提的是,最新版安装脚本已完全兼容 Ubuntu 24.04.1。这意味着我们可以直接进行系统安装,省去了先装早期版本再升级的繁琐步骤。

Choose an OS to install:1: Ubuntu Desktop 24.04.1 LTS2: Ubuntu Server 24.04.1 LTS3: Ubuntu Desktop 23.104: Ubuntu 22.04 LTS Server (unsupported)
» OS: 1

在 macOS 环境完成系统安装的第一阶段操作后,关闭设备并重新启动。在开机过程中,长按电源键直至出现引导选项界面。从中选择新安装的 Linux(Ubuntu)系统进行引导。

设备启动界面多了一个华丽的图标

首次切换至新系统时,设备会自动进入 macOS 恢复模式。此时,系统会要求输入当前主机的用户名和密码,以解锁系统并授权引导至非 macOS 系统。只需按照屏幕提示一步步操作即可完成此过程。

跟着安装要求照做,一路 “Next”

操作完成后,系统会自动重启并进入 Linux 环境。此时,您可能会发现显示器没有任何输出。这是因为 Linux 系统暂不支持通过雷电接口输出画面。要解决这个问题,只需将显示器连接线从雷电接口切换到 HDMI 接口即可。

将 DP 显示器接口切换为 HDMI

Mac Mini 的 Linux 启动速度非常快。片刻之间,熟悉的 Ubuntu 界面就会在连接的显示器上出现。

M2 Mac Mini Ubuntu 安装完毕

系统初始化后,首要任务是安装 SSH Server,以实现局域网内的远程管理功能。然而,在此之前,我们需要更新软件源以确保安装过程的效率和稳定性。

值得注意的是,随着系统版本的迭代,更新软件源的具体操作方法也发生了变化。

# 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 的命令。

apt update && apt upgrade -y
apt install openssh-server -y

接下来,我们就能够在终端输入 ssh [Mac Mini 局域网 IP 地址] 命令,来轻松地通过 SSH 远程管理它啦。

编译构建数据持久化 KV:Pika

Pika 是一款基于 RocksDB 存储引擎的高性能 KV 存储系统,它不仅完全兼容 Redis 协议,还支持持久化存储和多租户特性。作为 Redis 的有力补充,它支持 string、hash、list、zset、set、geo、hyperloglog、pubsub、bitmap、stream 等所有常用的 Redis 数据结构。

日常业务过程中,当 Redis 内存使用超过特定阈值(如 16GiB)时,往往会遇到以下挑战:内存容量受限、单线程处理导致阻塞、系统启动恢复耗时过长、内存硬件成本高昂、缓冲区易达到上限、主从切换开销巨大等问题。

Pika 在保持 Redis 协议兼容性和便捷运维特性的同时,通过持久化存储方案解决了 Redis 面临的大数据量存储瓶颈。此外,它还支持 slaveof 主从模式,并提供全量/增量数据同步功能。

由于官方暂未提供 ARM 平台的预编译二进制文件,我们需要通过源码自行构建。构建步骤非常简单,主要命令如下:

# 下载最近的正式发布版本
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

执行构建脚本后,系统首先会检查环境中是否包含所需的构建工具,随后自动下载项目的外部依赖包,并启动构建流程。在这个过程中,我们将看到类似下面的构建日志:

+ 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 编译峰值功耗

基础功能验证

接下来,我们可以通过以下命令对 Pika 进行基础功能验证(使用少量内存和大量磁盘提供等效 Redis 的服务):

./output/pika -c ./conf/pika.conf

运行命令后,终端将显示 Pika 在默认配置下的运行日志。

...
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 内存数据库性能测试

测试结果令我非常满意。这台设备不仅能耗极低、运行静音,还几乎跑满了设备本身的千兆网口,同时保留了充足的系统算力。

测试环境配置:

  • 网络环境:基于《千兆之上:家庭网络 2.5G 升级实践》搭建的 2.5G 内网
  • 服务端:Mac Mini M2(千兆网口,未安装 2.5G 网卡)
  • 测试端:MacBook Air M3

本次测试采用开源工具 Vire Benchmark。测试流程如下:

  • 通过 Docker 拉取预构建镜像
  • 启动容器
  • 执行性能测试:模拟 100 并发,向 Pika 发送 10 万次请求,测试 PINGSETGET 命令,每次请求携带 20KB 数据。

具体测试命令如下:

docker pull putianhui/vire-benchmark
docker run --rm -it putianhui/vire-benchmark bashvire-benchmark -h 10.11.12.93 -p 9221 -t ping,set,get -n 100000 -c 100 -d 20480

执行完成后,系统将返回如下测试结果:

====== PING_INLINE ======100000 requests completed in 2.35 seconds100 parallel clients20480 bytes payloadkeep alive: 116.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 seconds100 parallel clients20480 bytes payloadkeep alive: 112.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 作为设备的考量。既然设备已经到手,自然要一探究竟。

重新擦除设备系统后,查看系统情况概览

首先,让我们来看看这台二手 Mac Mini 的硬盘使用情况。拿到设备后,我立即进行了一次简单而关键的磁盘信息读取:

# smartctl -x /dev/disk0s1smartctl 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 PagesSupported Power States
St Op     Max   Active     Idle   RL RT WL WT  Ent_Lat  Ex_Lat0 +     0.00W       -        -    0  0  0  0        0       0=== START OF SMART DATA SECTION ===
SMART overall-health self-assessment test result: PASSEDSMART/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:      0Read 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 上编译了上一篇文章中的内存读写性能测试工具,并进行了三轮测试。

# 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 倍。

文章至此已近尾声,让我与各位喜欢折腾的朋友分享一下这次设备购入的成本和设备市场价格情况。

文章相关的设备二手市场价格

由于这台设备距离我近在咫尺,当晚(九点)即可验证方案可行性,我选择了以二手市场中较高的价格成交。考虑到设备几乎全新,且目前仅此类设备支持安装 Linux,这个价格或许仍算合理:平摊到五年,每年 700 元(云服务器等规格一个月 1200 元起)。

当然,若您不急于使用,耐心等待总能换来更优惠的价格。特别是随着 M4 芯片 Mac Mini 的普及,相信这类设备的价格必将进一步下探。

最后

至此,本次探索告一段落。等这段手头事情忙完后,我计划折腾一套集群方案。

当然,正如本次实践,期待合适的老款 Mac Mini M2 能回归理想价位。目前的设备价格略显偏高,尤其考虑到折扣后的 M4 版 Mac Mini 仅需 3500 元。

:D

祝大家玩的开心。

–EOF


我们有一个小小的折腾群,里面聚集了一些喜欢折腾、彼此坦诚相待的小伙伴。

我们在里面会一起聊聊软硬件、HomeLab、编程上、生活里以及职场中的一些问题,偶尔也在群里不定期的分享一些技术资料。

关于交友的标准,请参考下面的文章:

致新朋友:为生活投票,不断寻找更好的朋友

当然,通过下面这篇文章添加好友时,请备注实名和公司或学校、注明来源和目的,珍惜彼此的时间 😄

关于折腾群入群的那些事


如果你觉得内容还算实用,欢迎点赞分享给你的朋友,在此谢过。

如果你想更快的看到后续内容的更新,请戳 “点赞”、“分享”、“在看” ,这些免费的鼓励将会影响后续有关内容的更新速度。


本文使用「署名 4.0 国际 (CC BY 4.0)」许可协议,欢迎转载、或重新修改使用,但需要注明来源。 署名 4.0 国际 (CC BY 4.0)

本文作者: 苏洋

创建时间: 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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/478915.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

scala模式匹配

object test47 {def main(args: Array[String]): Unit {val id"445646546548858548648"//取出id前两位val provinceid.substring(0,2) // println(province) // if (province"42"){ // println("湖北") // }else if(province&quo…

第R4周:LSTM-火灾温度预测(TensorFlow版)

>- **&#x1f368; 本文为[&#x1f517;365天深度学习训练营]中的学习记录博客** >- **&#x1f356; 原作者&#xff1a;[K同学啊]** 往期文章可查阅&#xff1a; 深度学习总结 任务说明&#xff1a;数据集中提供了火灾温度&#xff08;Tem1&#xff09;、一氧化碳浓度…

transformer.js(三):底层架构及性能优化指南

Transformer.js 是一个轻量级、功能强大的 JavaScript 库&#xff0c;专注于在浏览器中运行 Transformer 模型&#xff0c;为前端开发者提供了高效实现自然语言处理&#xff08;NLP&#xff09;任务的能力。本文将详细解析 Transformer.js 的底层架构&#xff0c;并提供实用的性…

spf算法、三类LSA、区间防环路机制/规则、虚连接

1.构建spf树&#xff1a; 路由器将自己作为最短路经树的树根根据Router-LSA和Network-LSA中的拓扑信息,依次将Cost值最小的路由器添加到SPF树中。路由器以Router ID或者DR标识。广播网络中DR和其所连接路由器的Cost值为0。SPF树中只有单向的最短路径,保证了OSPF区域内路由计管不…

如何选择黑白相机和彩色相机

我们在选择成像解决方案时黑白相机很容易被忽略&#xff0c;因为许多新相机提供鲜艳的颜色&#xff0c;鲜明的对比度和改进的弱光性能。然而&#xff0c;有许多应用&#xff0c;选择黑白相机将是更好的选择&#xff0c;因为他们产生更清晰的图像&#xff0c;更好的分辨率&#…

【Flink】快速理解 FlinkCDC 2.0 原理

快速理解 FlinkCDC 2.0 原理 要详细理解 Flink CDC 原理可以看看这篇文章&#xff0c;讲得很详细&#xff1a;深入解析 Flink CDC 增量快照读取机制 (https://juejin.cn/post/7325370003192578075)。 FlnkCDC 2.0&#xff1a; Flink 2.x 引入了增量快照读取机制&#xff0c;…

AI智能体崛起:从“工具”到“助手”的进化之路

目录 AI智能体的崛起 AI智能体的定义与决策模型 AI智能体的特点与优势 AI智能体的应用与类型 面临的挑战 未来展望 近年来&#xff0c;人工智能领域的焦点正从传统的聊天机器人&#xff08;Chat Bot&#xff09;快速转向更具潜力的AI智能体&#xff08;AI Agent&#xff…

RAG架构类型

每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗&#xff1f;订阅我们的简报&#xff0c;深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同&#xff0c;从行业内部的深度分析和实用指南中受益。不要错过这个机会&#xff0c;成为AI领…

jmeter基础06_(练习)常见的http请求

课程大纲 上节课已经尝试进行了get请求&#xff0c;获取网站http://httpbin.org/的首页。 本节课使用网站“httpbin.org”演示几种基础的http请求。post、put、delete方法使用方法相同&#xff0c;所以仅以post为例来演示。 本节课所有请求仅填写&#xff1a;请求行、请求体。j…

SycoTec 4060 ER-S德国高精密主轴电机如何支持模具的自动化加工?

SycoTec 4060 ER-S高速电主轴在模具自动化加工中的支持体现在以下几个关键方面&#xff1a; 1.高精度与稳定性&#xff1a;SycoTec 4060 ER-S锥面跳动小于1微米&#xff0c;确保了加工过程中的极高精度&#xff0c;这对于模具的复杂几何形状和严格公差要求至关重要。高精度加工…

MySQL系列之数据类型(Numeric)

导览 前言一、数值类型综述二、数值类型详解1. NUMERIC1.1 UNSIGNED或SIGNED1.2 数据类型划分 2. Integer类型取值和存储要求3. Fixed-Point类型取值和存储要求4. Floating-Point类型取值和存储要求 结语精彩回放 前言 MySQL系列最近三篇均关注了和我们日常工作或学习密切相关…

Spring |(五)IoC/DI的注解开发

文章目录 &#x1f4da;核心容器&#x1f407;环境准备&#x1f407;容器的创建方式&#x1f407;bean的三种获取方式&#x1f407;BeanFactory的使用 &#x1f4da;IoC/DI注解开发&#x1f407;环境准备&#x1f407;注解开发定义bean&#x1f407;纯注解开发模式&#x1f407…

Linux -日志 | 线程池 | 线程安全 | 死锁

文章目录 1.日志1.1日志介绍1.2策略模式1.3实现日志类 2.线程池2.1线程池介绍2.2线程池的应用场景2.3线程池的设计2.4代码实现2.5修改为单例模式 3.线程安全和函数重入问题3.1线程安全和函数重入的概念3.2总结 4.死锁4.1什么是死锁4.2产生死锁的必要条件4.3避免死锁 1.日志 1.…

AI时代的PPT革命:智能生成PPT工具为何备受青睐?

在日常工作和学习中&#xff0c;PPT是我们不可或缺的表达工具。制作一份精美的PPT常常需要耗费数小时&#xff0c;甚至几天的时间。从选择主题到调整排版&#xff0c;琐碎的细节让人筋疲力尽。但现在一种名为“AI生成PPT”的技术正悄然崛起&#xff0c;彻底颠覆了传统PPT制作的…

结构方程模型(SEM)入门到精通:lavaan VS piecewiseSEM、全局估计/局域估计;潜变量分析、复合变量分析、贝叶斯SEM在生态学领域应用

目录 第一章 夯实基础 R/Rstudio简介及入门 第二章 结构方程模型&#xff08;SEM&#xff09;介绍 第三章 R语言SEM分析入门&#xff1a;lavaan VS piecewiseSEM 第四章 SEM全局估计&#xff08;lavaan&#xff09;在生态学领域高阶应用 第五章 SEM潜变量分析在生态学领域…

CANopen多电机控制的性能分析

在 CANopen 总线上控制多台电机并实时获取位置和速度信息&#xff0c;通信速度受到总线带宽、电机数量、数据刷新频率等因素影响。在 LabVIEW 开发中&#xff0c;利用 PDO 优化数据传输&#xff0c;合理设置刷新周期&#xff0c;并结合高效任务管理&#xff0c;可以显著提高多电…

图论入门编程

卡码网刷题链接&#xff1a;98. 所有可达路径 一、题目简述 二、编程demo 方法①邻接矩阵 from collections import defaultdict #简历邻接矩阵 def build_graph(): n, m map(int,input().split()) graph [[0 for _ in range(n1)] for _ in range(n1)]for _ in range(m): …

政安晨【零基础玩转各类开源AI项目】探索Cursor-AI Coder的应用实例

目录 Cusor的主要特点 Cusor实操 政安晨的个人主页&#xff1a;政安晨 欢迎 &#x1f44d;点赞✍评论⭐收藏 希望政安晨的博客能够对您有所裨益&#xff0c;如有不足之处&#xff0c;欢迎在评论区提出指正&#xff01; Cursor 是 Visual Studio Code 的一个分支。这使我们能够…

Taro 鸿蒙技术内幕系列(三) - 多语言场景下的通用事件系统设计

基于 Taro 打造的京东鸿蒙 APP 已跟随鸿蒙 Next 系统公测&#xff0c;本系列文章将深入解析 Taro 如何实现使用 React 开发高性能鸿蒙应用的技术内幕 背景 在鸿蒙生态系统中&#xff0c;虽然原生应用通常基于 ArkTS 实现&#xff0c;但在实际研发过程中发现&#xff0c;使用 C…

二,[ACTF2020 新生赛]Include1感谢 Y1ng 师傅供题。

进入靶场后&#xff0c;发现tips可以点击 点击后进入此页面 猜测此为文件上传漏洞,构造payload&#xff0c;并成功得到base64编码后的源码 详解payload&#xff1a; php://filter/readconvert.base64-encode/resourceflag.php 1.php://filter是PHP中的一个流封装协议&#xf…