当前位置: 首页 > news >正文

Mac 本地搭建 Redis 指南

Mac 本地搭建 Redis 指南

一、安装 Redis

方式一:Homebrew 安装(推荐)

# 安装
brew install redis# 验证安装
redis-server --version

方式二:Docker 安装

docker run -d --name redis -p 6379:6379 redis:latest

方式三:源码编译

curl -O http://download.redis.io/redis-stable.tar.gz
tar xzf redis-stable.tar.gz
cd redis-stable
make
make install

二、启动与停止

# 前台启动
redis-server# 后台服务方式启动(开机自启)
brew services start redis# 停止服务
brew services stop redis# 重启服务
brew services restart redis# 查看服务状态
brew services info redis

三、验证连接

# 连接本地 Redis
redis-cli# 测试连通性
redis-cli ping
# 返回 PONG 表示正常

四、项目配置

测试脚本和本项目均通过环境变量读取 Redis 配置,在 .env 文件中添加或通过命令行导出:

REDIS_HOST=127.0.0.1
REDIS_PORT=6379
REDIS_DB=0
REDIS_PASSWORD=
REDIS_TIMEOUT=5

如果本地 Redis 未设置密码,REDIS_PASSWORD 留空即可。

五、常用 redis-cli 命令

命令 说明
redis-cli 连接本地 Redis
redis-cli -h <host> -p <port> 连接指定地址
redis-cli -a <password> 带密码连接
redis-cli info 查看 Redis 信息
redis-cli dbsize 查看当前库 key 数量
redis-cli flushdb 清空当前库
redis-cli shutdown 关闭 Redis 服务

六、常用配置修改

Homebrew 安装的配置文件路径:

  • Apple Silicon:/opt/homebrew/etc/redis.conf
  • Intel Mac:/usr/local/etc/redis.conf

常见修改项:

# 设置密码
requirepass your_password# 允许远程访问(默认只允许本地)
bind 0.0.0.0# 修改端口
port 6379# 设置最大内存
maxmemory 256mb# 内存淘汰策略
maxmemory-policy allkeys-lru

修改后重启 Redis 生效:

brew services restart redis

七、运行测试程序

测试脚本为独立文件,不依赖本项目代码,唯一依赖:

pip install redis

确保 Redis 已启动后,直接运行:

python examples/test_local_redis.py

也可通过环境变量指定连接参数(默认连接 127.0.0.1:6379,无密码):

REDIS_HOST=127.0.0.1 REDIS_PORT=6379 python examples/test_local_redis.py

该脚本会依次测试连接、字符串读写、哈希、列表、集合、过期机制、Keys 模式匹配,最终输出通过/失败汇总。

点击查看代码
"""
本地 Redis 连接独立测试程序(无项目依赖)仅依赖第三方库:redis (>=4.2,含 redis.asyncio)
安装:pip install redis使用方式:1. 确保本地 Redis 已启动: redis-cli ping2. 直接运行: python test_local_redis.py3. 可通过环境变量覆盖默认配置:REDIS_HOST / REDIS_PORT / REDIS_DB / REDIS_PASSWORD / REDIS_TIMEOUT
"""import os
import asyncioimport redis.asyncio as aioredis# ───────── 配置(可通过环境变量覆盖)─────────REDIS_HOST = os.getenv("REDIS_HOST", "127.0.0.1")
REDIS_PORT = int(os.getenv("REDIS_PORT", "6379"))
REDIS_DB = int(os.getenv("REDIS_DB", "0"))
REDIS_PASSWORD = os.getenv("REDIS_PASSWORD") or None
REDIS_TIMEOUT = int(os.getenv("REDIS_TIMEOUT", "5"))# ───────── 测试统计 ─────────passed = 0
failed = 0def report(name: str, ok: bool, detail: str = ""):"""打印一条测试结果"""global passed, failedstatus = "PASS" if ok else "FAIL"if ok:passed += 1else:failed += 1msg = f"  [{status}] {name}"if detail:msg += f"  ({detail})"print(msg)# ───────── 连接管理 ─────────async def create_client() -> aioredis.Redis:"""创建一个本地 Redis 异步客户端"""pool = aioredis.ConnectionPool(host=REDIS_HOST,port=REDIS_PORT,db=REDIS_DB,password=REDIS_PASSWORD,decode_responses=True,socket_timeout=REDIS_TIMEOUT,socket_connect_timeout=REDIS_TIMEOUT,max_connections=10,)return aioredis.Redis(connection_pool=pool)# ───────── 测试用例 ─────────async def test_connection(client: aioredis.Redis) -> bool:"""测试 1:连接与 Ping"""print("\n--- 测试 1:连接与 Ping ---")try:pong = await client.ping()report("Redis 连接", bool(pong), f"{REDIS_HOST}:{REDIS_PORT}")return bool(pong)except Exception as e:report("Redis 连接", False, str(e))return Falseasync def test_string_ops(client: aioredis.Redis):"""测试 2:字符串读写"""print("\n--- 测试 2:字符串读写 ---")key = "test:string:hello"try:ok = await client.set(key, "world", ex=60)report("SET", bool(ok))val = await client.get(key)report("GET", val == "world", f"value={val}")exists = await client.exists(key)report("EXISTS", exists > 0)await client.delete(key)exists_after = await client.exists(key)report("DELETE", exists_after == 0)except Exception as e:report("字符串操作", False, str(e))async def test_hash_ops(client: aioredis.Redis):"""测试 3:哈希操作"""print("\n--- 测试 3:哈希操作 ---")key = "test:hash:user"try:await client.hset(key, "name", "test_user")await client.hset(key, "role", "developer")await client.expire(key, 60)name = await client.hget(key, "name")report("HSET / HGET", name == "test_user", f"name={name}")all_fields = await client.hgetall(key)report("HGETALL", len(all_fields) == 2, f"fields={all_fields}")await client.delete(key)except Exception as e:report("哈希操作", False, str(e))async def test_list_ops(client: aioredis.Redis):"""测试 4:列表操作"""print("\n--- 测试 4:列表操作 ---")key = "test:list:queue"try:await client.delete(key)await client.lpush(key, "a", "b", "c")await client.expire(key, 60)val = await client.rpop(key)report("LPUSH / RPOP", val == "a", f"popped={val}")await client.delete(key)except Exception as e:report("列表操作", False, str(e))async def test_set_ops(client: aioredis.Redis):"""测试 5:集合操作"""print("\n--- 测试 5:集合操作 ---")key = "test:set:tags"try:await client.delete(key)await client.sadd(key, "python", "redis", "mac")await client.expire(key, 60)members = await client.smembers(key)report("SADD / SMEMBERS", len(members) == 3, f"members={members}")await client.srem(key, "mac")members2 = await client.smembers(key)report("SREM", len(members2) == 2, f"after_remove={members2}")await client.delete(key)except Exception as e:report("集合操作", False, str(e))async def test_expire(client: aioredis.Redis):"""测试 6:过期机制"""print("\n--- 测试 6:过期机制 ---")key = "test:expire:tmp"try:await client.set(key, "will_expire", ex=2)val1 = await client.get(key)report("写入带过期的 key", val1 == "will_expire")print("    等待 3 秒让 key 过期...")await asyncio.sleep(3)val2 = await client.get(key)report("过期后 GET 为空", val2 is None, f"value={val2}")except Exception as e:report("过期机制", False, str(e))async def test_keys_pattern(client: aioredis.Redis):"""测试 7:Keys 模式匹配"""print("\n--- 测试 7:Keys 模式匹配 ---")try:await client.set("test:pattern:a", "1", ex=60)await client.set("test:pattern:b", "2", ex=60)keys = await client.keys("test:pattern:*")report("KEYS 模式匹配", len(keys) >= 2, f"found={len(keys)} keys")await client.delete("test:pattern:a", "test:pattern:b")except Exception as e:report("Keys 模式匹配", False, str(e))# ───────── 主入口 ─────────async def main():print("=" * 50)print(" Mac 本地 Redis 连接测试(独立版)")print("=" * 50)print(f"\n目标地址: {REDIS_HOST}:{REDIS_PORT}/{REDIS_DB}")print(f"密码: {'(已设置)' if REDIS_PASSWORD else '(无密码)'}")client = await create_client()try:connected = await test_connection(client)if not connected:print("\n连接失败,终止后续测试。请检查:")print("  1. Redis 是否已启动: redis-cli ping")print("  2. 主机/端口/密码是否正确(可通过 REDIS_HOST 等环境变量覆盖)")returnawait test_string_ops(client)await test_hash_ops(client)await test_list_ops(client)await test_set_ops(client)await test_expire(client)await test_keys_pattern(client)finally:try:await client.aclose()except Exception:pass# 汇总print("\n" + "=" * 50)total = passed + failedprint(f" 测试结果: {passed}/{total} 通过, {failed} 失败")if failed == 0:print(" 本地 Redis 一切正常!")else:print(" 存在失败项,请检查日志排查问题。")print("=" * 50)if __name__ == "__main__":asyncio.run(main())

执行 python examples/test_local_redis.py 效果如下:

==================================================Mac 本地 Redis 连接测试(独立版)
==================================================目标地址: 127.0.0.1:6379/0
密码: (无密码)--- 测试 1:连接与 Ping ---[PASS] Redis 连接  (127.0.0.1:6379)--- 测试 2:字符串读写 ---[PASS] SET[PASS] GET  (value=world)[PASS] EXISTS[PASS] DELETE--- 测试 3:哈希操作 ---[PASS] HSET / HGET  (name=test_user)[PASS] HGETALL  (fields={'name': 'test_user', 'role': 'developer'})--- 测试 4:列表操作 ---[PASS] LPUSH / RPOP  (popped=a)--- 测试 5:集合操作 ---[PASS] SADD / SMEMBERS  (members={'redis', 'python', 'mac'})[PASS] SREM  (after_remove={'redis', 'python'})--- 测试 6:过期机制 ---[PASS] 写入带过期的 key等待 3 秒让 key 过期...[PASS] 过期后 GET 为空  (value=None)--- 测试 7:Keys 模式匹配 ---[PASS] KEYS 模式匹配  (found=2 keys)==================================================测试结果: 13/13 通过, 0 失败本地 Redis 一切正常!
==================================================
http://www.jsqmd.com/news/725791/

相关文章:

  • 2026铁皮保温施工排行:实测性能与资质对比 铁皮保温施工 罐体保温施工 管道保温施工 厂家电话 - 奔跑123
  • 光子芯片测试速成
  • UnoCSS智能提示从失效到生效:我的踩坑记录与一份可用的uno.config.ts模板
  • 素颜可涂自然提亮防晒霜,太绝了,6款防晒霜不假白自然提亮一绝 - 全网最美
  • 内容创作团队如何借助Taotoken调用不同模型风格提升产出效率
  • HumDex: Humanoid Dexterous Manipulation Made Easy
  • doris脚本
  • 如何构建智能文档处理管道:Pix2Text开源OCR工具的实战应用指南
  • 传统美食如何通过淘宝抖音电商代运营走向全国?云麦电商的成功实践 - 深度智识库
  • 终极开源方案:专业解锁WeMod高级功能的完整指南
  • C# `BinaryPrimitives` 类详解
  • 铝皮保温包工包料施工厂家实测排行与性能对比 河北旭阔环保科技有限公司 厂家电话 - 奔跑123
  • 2026年新疆隐形车衣与乌鲁木齐汽车漆面保护膜完全选购指南 - 企业名录优选推荐
  • 告别鼠标手!Mac访达与终端高效互通的5个隐藏技巧(附Alfred5联动)
  • 别再浪费你的ADC了!用STM32的过采样功能,把12位ADC当14位用(附代码)
  • 【专利视点】光华经典案例八:答辩中关于发明克服了技术偏见的争辩
  • API测试(可删)
  • 告别臃肿!用注册表编辑器(Regedit)给你的Win10系统做一次深度“瘦身”
  • 终极指南:在Windows系统上高效安装安卓应用的专业方案
  • ubuntu 22.04 /etc/fstab 文件修改有误导致无法进入系统处理
  • 2026年武汉短视频代运营与GEO推广5大品牌深度横评:如何选择真正能转化的服务商 - 年度推荐企业名录
  • 自媒体人必看:如何用AI全自动生成爆款短视频
  • 别再只会kubectl logs了!这5个高阶参数和stern工具,让你排查K8s问题快人一步
  • 自动加好友这件事,其实用企业微信API就能搞定!
  • Windows系统直接安装APK的终极指南:告别模拟器时代
  • DeepSeek V4 逆向体验比预想中好用
  • 四川佳兴鼎盛商贸:成都建筑垃圾清运处置的机构 - LYL仔仔
  • 河南加之固建筑:上街区楼房室内墙改梁找哪家 - LYL仔仔
  • 如何快速下载全网小说?novel-downloader终极指南
  • C++ 回调函数学习笔记(从入门到理解)