突破内存限制: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 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。这意味着我们可以直接进行系统安装,省去了先装早期版本再升级的繁琐步骤。

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)系统进行引导。

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

首次切换至新系统时,设备会自动进入 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 bash

vire-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 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 作为设备的考量。既然设备已经到手,自然要一探究竟。

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

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

# 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 上编译了上一篇文章中的内存读写性能测试工具,并进行了三轮测试。

# 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

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

C++ 二叉搜索树(Binary Search Tree, BST)深度解析与全面指南:从基础概念到高级应用、算法优化及实战案例

&#x1f31f;个人主页&#xff1a;落叶 &#x1f31f;当前专栏: C专栏 目录 ⼆叉搜索树的概念 ⼆叉搜索树的性能分析 ⼆叉搜索树的插⼊ ⼆叉搜索树的查找 二叉搜索树中序遍历 ⼆叉搜索树的删除 cur的左节点为空的情况 cur的右节点为空的情况 左&#xff0c;右节点都不为…

数据库、数据仓库、数据湖、数据中台、湖仓一体的概念和区别

数据库、数据仓库、数据湖、数据中台和湖仓一体是数据管理和分析领域的不同概念&#xff0c;各自有不同的特点和应用场景。以下是它们的主要区别&#xff1a; 1. 数据库&#xff08;Database&#xff09; 定义&#xff1a;结构化的数据存储系统&#xff0c;用于高效地存储、检…

RabbitMQ原理架构解析:消息传递的核心机制

文章目录 一、RabbitMQ简介1.1、概述1.2、特性 二、RabbitMQ原理架构三、RabbitMQ应用场景3.1、简单模式3.2、工作模式3.3、发布订阅3.4、路由模式3.5 主题订阅模式 四、同类中间件对比五、RabbitMQ部署5.1、单机部署5.2、集群部署&#xff08;镜像模式&#xff09;5.3、K8s部署…

idea_常用设置

相关设置 项目的JDK设置out目录取消自动更新设置主题设置菜单和窗口字体大小滚轮调节字体大小显示行号与方法分隔符代码智能提示忽略大小写自动导包配置设置项目文件编码设置控制台的字符编码修改类头的文档注释信息设置自动编译 项目的JDK设置 File -> Project Structure -…

Redis的管道操作

在现代应用程序中&#xff0c;Redis作为一种高性能的内存数据库&#xff0c;被广泛用于缓存、消息队列、实时分析等场景。为了进一步提高Redis的性能&#xff0c;Redis提供了管道&#xff08;Pipeline&#xff09;操作&#xff0c;允许客户端将多个命令一次性发送到服务器&…

详解登录MySQL时出现SSL connection error: unknown error number错误

目录 登录MySQL时出错SSL connection error: unknown error number 出错原因 使用MySQL自带的工具登录MySQL 登陆之后&#xff0c;使用如下命令进行查看 解决方法 找到MySQL8安装目录下的my.ini配置文件 记事本打开my.ini文件&#xff0c;然后按下图所示添加配置 此时再…

E2、UML类图顺序图状态图实训

一、实验目的 在面向对象的设计里面&#xff0c;可维护性复用都是以面向对象设计原则为基础的&#xff0c;这些设计原则首先都是复用的原则&#xff0c;遵循这些设计原则可以有效地提高系统的复用性&#xff0c;同时提高系统的可维护性。在掌握面向对象七个设计原则基础上&…

Angular面试题汇总系列一

1. 如何理解Angular Signal Angular Signals is a system that granularly tracks how and where your state is used throughout an application, allowing the framework to optimize rendering updates. 什么是信号 信号是一个值的包装器&#xff0c;可以在该值发生变化时…

我要成为算法高手-递归篇

目录 题目1&#xff1a;汉诺塔题目2&#xff1a;合并两个有序链表题目3&#xff1a;反转链表题目4&#xff1a;两两交换链表中的结点题目5&#xff1a;Pow(x,n) 题目1&#xff1a;汉诺塔 面试题 08.06. 汉诺塔问题 - 力扣&#xff08;LeetCode&#xff09; 解题思路&#xff1…

【大数据技术基础】 课程 第8章 数据仓库Hive的安装和使用 大数据基础编程、实验和案例教程(第2版)

第8章 数据仓库Hive的安装和使用 8.1 Hive的安装 8.1.1 下载安装文件 访问Hive官网&#xff08;http://www.apache.org/dyn/closer.cgi/hive/&#xff09;下载安装文件apache-hive-3.1.2-bin.tar.gz 下载完安装文件以后&#xff0c;需要对文件进行解压。按照Linux系统使用的…

js.二叉树的层序遍历2

链接&#xff1a;107. 二叉树的层序遍历 II - 力扣&#xff08;LeetCode&#xff09; 题目&#xff1a; 给你二叉树的根节点 root &#xff0c;返回其节点值 自底向上的层序遍历 。 &#xff08;即按从叶子节点所在层到根节点所在的层&#xff0c;逐层从左向右遍历&#xff09…

kafka生产者和消费者命令的使用

kafka-console-producer.sh 生产数据 # 发送信息 指定topic即可 kafka-console-producer.sh \ --bootstrap-server bigdata01:9092 \ --topic topicA # 主题# 进程 29124 ConsoleProducer kafka-console-consumer.sh 消费数据 # 消费数据 kafka-console-consumer.sh \ --boo…

基于Springboot的心灵治愈交流平台系统的设计与实现

基于Springboot的心灵治愈交流平台系统 介绍 基于Springboot的心灵治愈交流平台系统&#xff0c;后端框架使用Springboot和mybatis&#xff0c;前端框架使用Vuehrml&#xff0c;数据库使用mysql&#xff0c;使用B/S架构实现前台用户系统和后台管理员系统&#xff0c;和不同级别…

从入门到精通数据结构----四大排序(上)

目录 首言&#xff1a; 1. 插入排序 1.1 直接插入排序 1.2 希尔排序 2. 选择排序 2.1 直接选择排序 2.2 堆排序 3. 交换排序 3.1 冒泡排序 3.2 快排 结尾&#xff1a; 首言&#xff1a; 本篇文章主要介绍常见的四大排序&#xff1a;交换排序、选择排序、插入排序、归并排…

SpringCloud+SpringCloudAlibaba学习笔记

SpringCloud 服务注册中心 eureka ap 高可用 分布式容错 <dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-eureka-server</artifactId> </dependency> <dependency><groupId…

Sentinel服务保护

Sentinel是阿里巴巴开源的一款服务保护框架&#xff0c;目前已经加入SpringCloudAlibaba中。官方网站&#xff1a; home | Sentinel Sentinel 的使用可以分为两个部分: 核心库&#xff08;Jar包&#xff09;&#xff1a;不依赖任何框架/库&#xff0c;能够运行于 Java 8 及以…

【Redis 】Bitmap 使用

Redis Bitmap介绍 Redis Bitmap 是一种特殊的数据类型&#xff0c;它通过字符串类型键来存储一系列连续的二进制位&#xff08;bits&#xff09;&#xff0c;每个位可以独立地表示一个布尔值&#xff08;0 或 1&#xff09;。这种数据结构非常适合用于存储和操作大量二值状态的…

【spark-spring boot】学习笔记

目录 说明RDD学习RDD介绍RDD案例基于集合创建RDDRDD存入外部文件中 转换算子 操作map 操作说明案例 flatMap操作说明案例 filter 操作说明案例 groupBy 操作说明案例 distinct 操作说明案例 sortBy 操作说明案例 mapToPair 操作说明案例 mapValues操作说明案例 groupByKey操作说…

C++ 红黑树:红黑树的插入及应用(map与set的封装)

目录 红黑树 红黑树的概念 红黑树的性质 红黑树节点的定义 一、如果默认给黑色 二、如果默认给红色 红黑树的插入操作 1.按搜索树的规则进行插入 2.检测新节点插入后&#xff0c;红黑树的性质是否造到破坏 情况一&#xff1a;cur为红&#xff0c;parent为红&#xff…

elementUI非常规数据格式渲染复杂表格(副表头、合并单元格)

效果 数据源 前端代码 (展示以及表格处理/数据处理) 标签 <el-table :data"dataList" style"width: 100%" :span-method"objectSpanMethod"><template v-for"(item, index) in headers"><el-table-column prop"…