[{"data":1,"prerenderedAt":1536},["ShallowReactive",2],{"doc-page:\u002Fdocs\u002Fredis-guide":3},{"doc":4,"prev":1496,"next":1503,"resolvedType":8,"readingMinutes":111,"audience":1510,"checklist":1514,"related":1518},{"path":5,"title":6,"description":7,"docType":8,"resourceKind":9,"categoryId":10,"categoryLabel":11,"updatedAt":12,"publishedAt":12,"icon":13,"body":14},"\u002Fdocs\u002Fredis-guide","Redis 使用指南","Redis 安装、数据类型、常用命令、缓存策略与 Node.js 集成","article",null,"programming-languages","编程语言","2026-02-28","i-carbon-application",{"type":15,"value":16,"toc":1472},"minimark",[17,21,32,35,40,56,59,70,73,78,166,170,193,196,662,666,669,685,1002,1005,1009,1171,1174,1252,1256,1391,1394,1397,1412,1415,1419,1422,1426,1429,1433,1436,1468],[18,19,6],"h1",{"id":20},"redis-使用指南",[22,23,24,31],"p",{},[25,26,30],"a",{"href":27,"rel":28},"https:\u002F\u002Fredis.io\u002F",[29],"nofollow","Redis"," 是高性能的内存键值数据库，常用于缓存、会话管理和消息队列。",[22,33,34],{},"如果你第一次接触 Redis，最重要的不是把所有数据类型都背下来，而是先理解：它为什么快、适合放什么、不适合放什么。",[36,37,39],"h2",{"id":38},"先理解-redis-适合什么","先理解 Redis 适合什么",[41,42,43,47,50,53],"ul",{},[44,45,46],"li",{},"短期缓存",[44,48,49],{},"会话和验证码",[44,51,52],{},"排行榜、计数器",[44,54,55],{},"轻量消息通知",[36,57,58],{"id":58},"不太适合直接拿来做什么",[41,60,61,64,67],{},[44,62,63],{},"唯一持久化主数据库",[44,65,66],{},"复杂关系查询",[44,68,69],{},"没有过期策略的大量临时数据堆积",[36,71,72],{"id":72},"安装",[74,75,77],"h3",{"id":76},"docker推荐","Docker（推荐）",[79,80,85],"pre",{"className":81,"code":82,"language":83,"meta":84,"style":84},"language-yaml shiki shiki-themes github-light github-dark","services:\n  redis:\n    image: redis:7-alpine\n    ports:\n      - \"6379:6379\"\n    volumes:\n      - .\u002Fredis-data:\u002Fdata\n    command: redis-server --appendonly yes\n","yaml","",[86,87,88,101,109,122,130,139,147,155],"code",{"__ignoreMap":84},[89,90,93,97],"span",{"class":91,"line":92},"line",1,[89,94,96],{"class":95},"s9eBZ","services",[89,98,100],{"class":99},"sVt8B",":\n",[89,102,104,107],{"class":91,"line":103},2,[89,105,106],{"class":95},"  redis",[89,108,100],{"class":99},[89,110,112,115,118],{"class":91,"line":111},3,[89,113,114],{"class":95},"    image",[89,116,117],{"class":99},": ",[89,119,121],{"class":120},"sZZnC","redis:7-alpine\n",[89,123,125,128],{"class":91,"line":124},4,[89,126,127],{"class":95},"    ports",[89,129,100],{"class":99},[89,131,133,136],{"class":91,"line":132},5,[89,134,135],{"class":99},"      - ",[89,137,138],{"class":120},"\"6379:6379\"\n",[89,140,142,145],{"class":91,"line":141},6,[89,143,144],{"class":95},"    volumes",[89,146,100],{"class":99},[89,148,150,152],{"class":91,"line":149},7,[89,151,135],{"class":99},[89,153,154],{"class":120},".\u002Fredis-data:\u002Fdata\n",[89,156,158,161,163],{"class":91,"line":157},8,[89,159,160],{"class":95},"    command",[89,162,117],{"class":99},[89,164,165],{"class":120},"redis-server --appendonly yes\n",[74,167,169],{"id":168},"windows","Windows",[79,171,175],{"className":172,"code":173,"language":174,"meta":84,"style":84},"language-powershell shiki shiki-themes github-light github-dark","scoop install redis\n# 或使用 Memurai（Windows 原生 Redis 兼容）\nwinget install Memurai.MemuraiDeveloper\n","powershell",[86,176,177,182,188],{"__ignoreMap":84},[89,178,179],{"class":91,"line":92},[89,180,181],{"class":99},"scoop install redis\n",[89,183,184],{"class":91,"line":103},[89,185,187],{"class":186},"sJ8bj","# 或使用 Memurai（Windows 原生 Redis 兼容）\n",[89,189,190],{"class":91,"line":111},[89,191,192],{"class":99},"winget install Memurai.MemuraiDeveloper\n",[36,194,195],{"id":195},"常用命令",[79,197,201],{"className":198,"code":199,"language":200,"meta":84,"style":84},"language-bash shiki shiki-themes github-light github-dark","# 连接\nredis-cli\nredis-cli -h 127.0.0.1 -p 6379\n\n# 字符串\nSET name \"Domi\"\nGET name\nSET token \"abc\" EX 3600        # 1 小时过期\nTTL token                      # 查看剩余时间\nDEL name                       # 删除\nINCR counter                   # 自增\nINCRBY counter 5               # 增加指定值\n\n# 哈希\nHSET user:1 name \"Domi\" age 20\nHGET user:1 name\nHGETALL user:1\nHDEL user:1 age\n\n# 列表\nLPUSH queue \"task1\"\nRPUSH queue \"task2\"\nLPOP queue\nLRANGE queue 0 -1              # 查看所有\n\n# 集合\nSADD tags \"vue\" \"nuxt\" \"ts\"\nSMEMBERS tags\nSISMEMBER tags \"vue\"\n\n# 有序集合\nZADD leaderboard 100 \"player1\" 200 \"player2\"\nZRANGE leaderboard 0 -1 WITHSCORES\nZREVRANGE leaderboard 0 2      # Top 3\n\n# 通用\nKEYS user:*                    # 查找键（生产慎用）\nSCAN 0 MATCH user:* COUNT 100 # 安全遍历\nEXISTS name\nEXPIRE name 60                 # 设置过期\nTYPE name                      # 查看类型\nDBSIZE                         # 键总数\nFLUSHDB                        # 清空当前库\n","bash",[86,202,203,208,214,232,238,243,254,262,281,292,303,315,329,334,340,360,370,379,390,395,401,413,424,433,450,455,461,479,488,499,504,510,531,546,562,567,573,588,611,619,633,644,653],{"__ignoreMap":84},[89,204,205],{"class":91,"line":92},[89,206,207],{"class":186},"# 连接\n",[89,209,210],{"class":91,"line":103},[89,211,213],{"class":212},"sScJk","redis-cli\n",[89,215,216,219,223,226,229],{"class":91,"line":111},[89,217,218],{"class":212},"redis-cli",[89,220,222],{"class":221},"sj4cs"," -h",[89,224,225],{"class":221}," 127.0.0.1",[89,227,228],{"class":221}," -p",[89,230,231],{"class":221}," 6379\n",[89,233,234],{"class":91,"line":124},[89,235,237],{"emptyLinePlaceholder":236},true,"\n",[89,239,240],{"class":91,"line":132},[89,241,242],{"class":186},"# 字符串\n",[89,244,245,248,251],{"class":91,"line":141},[89,246,247],{"class":212},"SET",[89,249,250],{"class":120}," name",[89,252,253],{"class":120}," \"Domi\"\n",[89,255,256,259],{"class":91,"line":149},[89,257,258],{"class":212},"GET",[89,260,261],{"class":120}," name\n",[89,263,264,266,269,272,275,278],{"class":91,"line":157},[89,265,247],{"class":212},[89,267,268],{"class":120}," token",[89,270,271],{"class":120}," \"abc\"",[89,273,274],{"class":120}," EX",[89,276,277],{"class":221}," 3600",[89,279,280],{"class":186},"        # 1 小时过期\n",[89,282,284,287,289],{"class":91,"line":283},9,[89,285,286],{"class":212},"TTL",[89,288,268],{"class":120},[89,290,291],{"class":186},"                      # 查看剩余时间\n",[89,293,295,298,300],{"class":91,"line":294},10,[89,296,297],{"class":212},"DEL",[89,299,250],{"class":120},[89,301,302],{"class":186},"                       # 删除\n",[89,304,306,309,312],{"class":91,"line":305},11,[89,307,308],{"class":212},"INCR",[89,310,311],{"class":120}," counter",[89,313,314],{"class":186},"                   # 自增\n",[89,316,318,321,323,326],{"class":91,"line":317},12,[89,319,320],{"class":212},"INCRBY",[89,322,311],{"class":120},[89,324,325],{"class":221}," 5",[89,327,328],{"class":186},"               # 增加指定值\n",[89,330,332],{"class":91,"line":331},13,[89,333,237],{"emptyLinePlaceholder":236},[89,335,337],{"class":91,"line":336},14,[89,338,339],{"class":186},"# 哈希\n",[89,341,343,346,349,351,354,357],{"class":91,"line":342},15,[89,344,345],{"class":212},"HSET",[89,347,348],{"class":120}," user:1",[89,350,250],{"class":120},[89,352,353],{"class":120}," \"Domi\"",[89,355,356],{"class":120}," age",[89,358,359],{"class":221}," 20\n",[89,361,363,366,368],{"class":91,"line":362},16,[89,364,365],{"class":212},"HGET",[89,367,348],{"class":120},[89,369,261],{"class":120},[89,371,373,376],{"class":91,"line":372},17,[89,374,375],{"class":212},"HGETALL",[89,377,378],{"class":120}," user:1\n",[89,380,382,385,387],{"class":91,"line":381},18,[89,383,384],{"class":212},"HDEL",[89,386,348],{"class":120},[89,388,389],{"class":120}," age\n",[89,391,393],{"class":91,"line":392},19,[89,394,237],{"emptyLinePlaceholder":236},[89,396,398],{"class":91,"line":397},20,[89,399,400],{"class":186},"# 列表\n",[89,402,404,407,410],{"class":91,"line":403},21,[89,405,406],{"class":212},"LPUSH",[89,408,409],{"class":120}," queue",[89,411,412],{"class":120}," \"task1\"\n",[89,414,416,419,421],{"class":91,"line":415},22,[89,417,418],{"class":212},"RPUSH",[89,420,409],{"class":120},[89,422,423],{"class":120}," \"task2\"\n",[89,425,427,430],{"class":91,"line":426},23,[89,428,429],{"class":212},"LPOP",[89,431,432],{"class":120}," queue\n",[89,434,436,439,441,444,447],{"class":91,"line":435},24,[89,437,438],{"class":212},"LRANGE",[89,440,409],{"class":120},[89,442,443],{"class":221}," 0",[89,445,446],{"class":221}," -1",[89,448,449],{"class":186},"              # 查看所有\n",[89,451,453],{"class":91,"line":452},25,[89,454,237],{"emptyLinePlaceholder":236},[89,456,458],{"class":91,"line":457},26,[89,459,460],{"class":186},"# 集合\n",[89,462,464,467,470,473,476],{"class":91,"line":463},27,[89,465,466],{"class":212},"SADD",[89,468,469],{"class":120}," tags",[89,471,472],{"class":120}," \"vue\"",[89,474,475],{"class":120}," \"nuxt\"",[89,477,478],{"class":120}," \"ts\"\n",[89,480,482,485],{"class":91,"line":481},28,[89,483,484],{"class":212},"SMEMBERS",[89,486,487],{"class":120}," tags\n",[89,489,491,494,496],{"class":91,"line":490},29,[89,492,493],{"class":212},"SISMEMBER",[89,495,469],{"class":120},[89,497,498],{"class":120}," \"vue\"\n",[89,500,502],{"class":91,"line":501},30,[89,503,237],{"emptyLinePlaceholder":236},[89,505,507],{"class":91,"line":506},31,[89,508,509],{"class":186},"# 有序集合\n",[89,511,513,516,519,522,525,528],{"class":91,"line":512},32,[89,514,515],{"class":212},"ZADD",[89,517,518],{"class":120}," leaderboard",[89,520,521],{"class":221}," 100",[89,523,524],{"class":120}," \"player1\"",[89,526,527],{"class":221}," 200",[89,529,530],{"class":120}," \"player2\"\n",[89,532,534,537,539,541,543],{"class":91,"line":533},33,[89,535,536],{"class":212},"ZRANGE",[89,538,518],{"class":120},[89,540,443],{"class":221},[89,542,446],{"class":221},[89,544,545],{"class":120}," WITHSCORES\n",[89,547,549,552,554,556,559],{"class":91,"line":548},34,[89,550,551],{"class":212},"ZREVRANGE",[89,553,518],{"class":120},[89,555,443],{"class":221},[89,557,558],{"class":221}," 2",[89,560,561],{"class":186},"      # Top 3\n",[89,563,565],{"class":91,"line":564},35,[89,566,237],{"emptyLinePlaceholder":236},[89,568,570],{"class":91,"line":569},36,[89,571,572],{"class":186},"# 通用\n",[89,574,576,579,582,585],{"class":91,"line":575},37,[89,577,578],{"class":212},"KEYS",[89,580,581],{"class":120}," user:",[89,583,584],{"class":221},"*",[89,586,587],{"class":186},"                    # 查找键（生产慎用）\n",[89,589,591,594,596,599,601,603,606,608],{"class":91,"line":590},38,[89,592,593],{"class":212},"SCAN",[89,595,443],{"class":221},[89,597,598],{"class":120}," MATCH",[89,600,581],{"class":120},[89,602,584],{"class":221},[89,604,605],{"class":120}," COUNT",[89,607,521],{"class":221},[89,609,610],{"class":186}," # 安全遍历\n",[89,612,614,617],{"class":91,"line":613},39,[89,615,616],{"class":212},"EXISTS",[89,618,261],{"class":120},[89,620,622,625,627,630],{"class":91,"line":621},40,[89,623,624],{"class":212},"EXPIRE",[89,626,250],{"class":120},[89,628,629],{"class":221}," 60",[89,631,632],{"class":186},"                 # 设置过期\n",[89,634,636,639,641],{"class":91,"line":635},41,[89,637,638],{"class":212},"TYPE",[89,640,250],{"class":120},[89,642,643],{"class":186},"                      # 查看类型\n",[89,645,647,650],{"class":91,"line":646},42,[89,648,649],{"class":212},"DBSIZE",[89,651,652],{"class":186},"                         # 键总数\n",[89,654,656,659],{"class":91,"line":655},43,[89,657,658],{"class":212},"FLUSHDB",[89,660,661],{"class":186},"                        # 清空当前库\n",[36,663,665],{"id":664},"nodejs-集成","Node.js 集成",[74,667,668],{"id":668},"ioredis",[79,670,672],{"className":198,"code":671,"language":200,"meta":84,"style":84},"pnpm add ioredis\n",[86,673,674],{"__ignoreMap":84},[89,675,676,679,682],{"class":91,"line":92},[89,677,678],{"class":212},"pnpm",[89,680,681],{"class":120}," add",[89,683,684],{"class":120}," ioredis\n",[79,686,690],{"className":687,"code":688,"language":689,"meta":84,"style":84},"language-typescript shiki shiki-themes github-light github-dark","import Redis from \"ioredis\";\n\nconst redis = new Redis({\n  host: \"127.0.0.1\",\n  port: 6379,\n});\n\n\u002F\u002F 基础操作\nawait redis.set(\"key\", \"value\");\nawait redis.set(\"token\", \"abc\", \"EX\", 3600);\nconst val = await redis.get(\"key\");\n\n\u002F\u002F 哈希\nawait redis.hset(\"user:1\", { name: \"Domi\", age: \"20\" });\nconst user = await redis.hgetall(\"user:1\");\n\n\u002F\u002F 管道（批量操作）\nconst pipeline = redis.pipeline();\npipeline.set(\"a\", \"1\");\npipeline.set(\"b\", \"2\");\npipeline.get(\"a\");\nconst results = await pipeline.exec();\n","typescript",[86,691,692,710,714,734,745,755,760,764,769,795,825,848,852,857,886,908,912,917,934,953,971,983],{"__ignoreMap":84},[89,693,694,698,701,704,707],{"class":91,"line":92},[89,695,697],{"class":696},"szBVR","import",[89,699,700],{"class":99}," Redis ",[89,702,703],{"class":696},"from",[89,705,706],{"class":120}," \"ioredis\"",[89,708,709],{"class":99},";\n",[89,711,712],{"class":91,"line":103},[89,713,237],{"emptyLinePlaceholder":236},[89,715,716,719,722,725,728,731],{"class":91,"line":111},[89,717,718],{"class":696},"const",[89,720,721],{"class":221}," redis",[89,723,724],{"class":696}," =",[89,726,727],{"class":696}," new",[89,729,730],{"class":212}," Redis",[89,732,733],{"class":99},"({\n",[89,735,736,739,742],{"class":91,"line":124},[89,737,738],{"class":99},"  host: ",[89,740,741],{"class":120},"\"127.0.0.1\"",[89,743,744],{"class":99},",\n",[89,746,747,750,753],{"class":91,"line":132},[89,748,749],{"class":99},"  port: ",[89,751,752],{"class":221},"6379",[89,754,744],{"class":99},[89,756,757],{"class":91,"line":141},[89,758,759],{"class":99},"});\n",[89,761,762],{"class":91,"line":149},[89,763,237],{"emptyLinePlaceholder":236},[89,765,766],{"class":91,"line":157},[89,767,768],{"class":186},"\u002F\u002F 基础操作\n",[89,770,771,774,777,780,783,786,789,792],{"class":91,"line":283},[89,772,773],{"class":696},"await",[89,775,776],{"class":99}," redis.",[89,778,779],{"class":212},"set",[89,781,782],{"class":99},"(",[89,784,785],{"class":120},"\"key\"",[89,787,788],{"class":99},", ",[89,790,791],{"class":120},"\"value\"",[89,793,794],{"class":99},");\n",[89,796,797,799,801,803,805,808,810,813,815,818,820,823],{"class":91,"line":294},[89,798,773],{"class":696},[89,800,776],{"class":99},[89,802,779],{"class":212},[89,804,782],{"class":99},[89,806,807],{"class":120},"\"token\"",[89,809,788],{"class":99},[89,811,812],{"class":120},"\"abc\"",[89,814,788],{"class":99},[89,816,817],{"class":120},"\"EX\"",[89,819,788],{"class":99},[89,821,822],{"class":221},"3600",[89,824,794],{"class":99},[89,826,827,829,832,834,837,839,842,844,846],{"class":91,"line":305},[89,828,718],{"class":696},[89,830,831],{"class":221}," val",[89,833,724],{"class":696},[89,835,836],{"class":696}," await",[89,838,776],{"class":99},[89,840,841],{"class":212},"get",[89,843,782],{"class":99},[89,845,785],{"class":120},[89,847,794],{"class":99},[89,849,850],{"class":91,"line":317},[89,851,237],{"emptyLinePlaceholder":236},[89,853,854],{"class":91,"line":331},[89,855,856],{"class":186},"\u002F\u002F 哈希\n",[89,858,859,861,863,866,868,871,874,877,880,883],{"class":91,"line":336},[89,860,773],{"class":696},[89,862,776],{"class":99},[89,864,865],{"class":212},"hset",[89,867,782],{"class":99},[89,869,870],{"class":120},"\"user:1\"",[89,872,873],{"class":99},", { name: ",[89,875,876],{"class":120},"\"Domi\"",[89,878,879],{"class":99},", age: ",[89,881,882],{"class":120},"\"20\"",[89,884,885],{"class":99}," });\n",[89,887,888,890,893,895,897,899,902,904,906],{"class":91,"line":342},[89,889,718],{"class":696},[89,891,892],{"class":221}," user",[89,894,724],{"class":696},[89,896,836],{"class":696},[89,898,776],{"class":99},[89,900,901],{"class":212},"hgetall",[89,903,782],{"class":99},[89,905,870],{"class":120},[89,907,794],{"class":99},[89,909,910],{"class":91,"line":362},[89,911,237],{"emptyLinePlaceholder":236},[89,913,914],{"class":91,"line":372},[89,915,916],{"class":186},"\u002F\u002F 管道（批量操作）\n",[89,918,919,921,924,926,928,931],{"class":91,"line":381},[89,920,718],{"class":696},[89,922,923],{"class":221}," pipeline",[89,925,724],{"class":696},[89,927,776],{"class":99},[89,929,930],{"class":212},"pipeline",[89,932,933],{"class":99},"();\n",[89,935,936,939,941,943,946,948,951],{"class":91,"line":392},[89,937,938],{"class":99},"pipeline.",[89,940,779],{"class":212},[89,942,782],{"class":99},[89,944,945],{"class":120},"\"a\"",[89,947,788],{"class":99},[89,949,950],{"class":120},"\"1\"",[89,952,794],{"class":99},[89,954,955,957,959,961,964,966,969],{"class":91,"line":397},[89,956,938],{"class":99},[89,958,779],{"class":212},[89,960,782],{"class":99},[89,962,963],{"class":120},"\"b\"",[89,965,788],{"class":99},[89,967,968],{"class":120},"\"2\"",[89,970,794],{"class":99},[89,972,973,975,977,979,981],{"class":91,"line":403},[89,974,938],{"class":99},[89,976,841],{"class":212},[89,978,782],{"class":99},[89,980,945],{"class":120},[89,982,794],{"class":99},[89,984,985,987,990,992,994,997,1000],{"class":91,"line":415},[89,986,718],{"class":696},[89,988,989],{"class":221}," results",[89,991,724],{"class":696},[89,993,836],{"class":696},[89,995,996],{"class":99}," pipeline.",[89,998,999],{"class":212},"exec",[89,1001,933],{"class":99},[36,1003,1004],{"id":1004},"缓存策略",[74,1006,1008],{"id":1007},"cache-aside","Cache-Aside",[79,1010,1012],{"className":687,"code":1011,"language":689,"meta":84,"style":84},"async function getUser(id: string) {\n  const cached = await redis.get(`user:${id}`);\n  if (cached) return JSON.parse(cached);\n\n  const user = await db.query(\"SELECT * FROM users WHERE id = $1\", [id]);\n  await redis.set(`user:${id}`, JSON.stringify(user), \"EX\", 300);\n  return user;\n}\n",[86,1013,1014,1040,1068,1091,1095,1119,1158,1166],{"__ignoreMap":84},[89,1015,1016,1019,1022,1025,1027,1031,1034,1037],{"class":91,"line":92},[89,1017,1018],{"class":696},"async",[89,1020,1021],{"class":696}," function",[89,1023,1024],{"class":212}," getUser",[89,1026,782],{"class":99},[89,1028,1030],{"class":1029},"s4XuR","id",[89,1032,1033],{"class":696},":",[89,1035,1036],{"class":221}," string",[89,1038,1039],{"class":99},") {\n",[89,1041,1042,1045,1048,1050,1052,1054,1056,1058,1061,1063,1066],{"class":91,"line":103},[89,1043,1044],{"class":696},"  const",[89,1046,1047],{"class":221}," cached",[89,1049,724],{"class":696},[89,1051,836],{"class":696},[89,1053,776],{"class":99},[89,1055,841],{"class":212},[89,1057,782],{"class":99},[89,1059,1060],{"class":120},"`user:${",[89,1062,1030],{"class":99},[89,1064,1065],{"class":120},"}`",[89,1067,794],{"class":99},[89,1069,1070,1073,1076,1079,1082,1085,1088],{"class":91,"line":111},[89,1071,1072],{"class":696},"  if",[89,1074,1075],{"class":99}," (cached) ",[89,1077,1078],{"class":696},"return",[89,1080,1081],{"class":221}," JSON",[89,1083,1084],{"class":99},".",[89,1086,1087],{"class":212},"parse",[89,1089,1090],{"class":99},"(cached);\n",[89,1092,1093],{"class":91,"line":124},[89,1094,237],{"emptyLinePlaceholder":236},[89,1096,1097,1099,1101,1103,1105,1108,1111,1113,1116],{"class":91,"line":132},[89,1098,1044],{"class":696},[89,1100,892],{"class":221},[89,1102,724],{"class":696},[89,1104,836],{"class":696},[89,1106,1107],{"class":99}," db.",[89,1109,1110],{"class":212},"query",[89,1112,782],{"class":99},[89,1114,1115],{"class":120},"\"SELECT * FROM users WHERE id = $1\"",[89,1117,1118],{"class":99},", [id]);\n",[89,1120,1121,1124,1126,1128,1130,1132,1134,1136,1138,1141,1143,1146,1149,1151,1153,1156],{"class":91,"line":141},[89,1122,1123],{"class":696},"  await",[89,1125,776],{"class":99},[89,1127,779],{"class":212},[89,1129,782],{"class":99},[89,1131,1060],{"class":120},[89,1133,1030],{"class":99},[89,1135,1065],{"class":120},[89,1137,788],{"class":99},[89,1139,1140],{"class":221},"JSON",[89,1142,1084],{"class":99},[89,1144,1145],{"class":212},"stringify",[89,1147,1148],{"class":99},"(user), ",[89,1150,817],{"class":120},[89,1152,788],{"class":99},[89,1154,1155],{"class":221},"300",[89,1157,794],{"class":99},[89,1159,1160,1163],{"class":91,"line":149},[89,1161,1162],{"class":696},"  return",[89,1164,1165],{"class":99}," user;\n",[89,1167,1168],{"class":91,"line":157},[89,1169,1170],{"class":99},"}\n",[74,1172,1173],{"id":1173},"缓存失效",[79,1175,1177],{"className":687,"code":1176,"language":689,"meta":84,"style":84},"\u002F\u002F 更新时删除缓存\nasync function updateUser(id: string, data: any) {\n  await db.query(\"UPDATE users SET name = $1 WHERE id = $2\", [data.name, id]);\n  await redis.del(`user:${id}`);\n}\n",[86,1178,1179,1184,1213,1229,1248],{"__ignoreMap":84},[89,1180,1181],{"class":91,"line":92},[89,1182,1183],{"class":186},"\u002F\u002F 更新时删除缓存\n",[89,1185,1186,1188,1190,1193,1195,1197,1199,1201,1203,1206,1208,1211],{"class":91,"line":103},[89,1187,1018],{"class":696},[89,1189,1021],{"class":696},[89,1191,1192],{"class":212}," updateUser",[89,1194,782],{"class":99},[89,1196,1030],{"class":1029},[89,1198,1033],{"class":696},[89,1200,1036],{"class":221},[89,1202,788],{"class":99},[89,1204,1205],{"class":1029},"data",[89,1207,1033],{"class":696},[89,1209,1210],{"class":221}," any",[89,1212,1039],{"class":99},[89,1214,1215,1217,1219,1221,1223,1226],{"class":91,"line":111},[89,1216,1123],{"class":696},[89,1218,1107],{"class":99},[89,1220,1110],{"class":212},[89,1222,782],{"class":99},[89,1224,1225],{"class":120},"\"UPDATE users SET name = $1 WHERE id = $2\"",[89,1227,1228],{"class":99},", [data.name, id]);\n",[89,1230,1231,1233,1235,1238,1240,1242,1244,1246],{"class":91,"line":124},[89,1232,1123],{"class":696},[89,1234,776],{"class":99},[89,1236,1237],{"class":212},"del",[89,1239,782],{"class":99},[89,1241,1060],{"class":120},[89,1243,1030],{"class":99},[89,1245,1065],{"class":120},[89,1247,794],{"class":99},[89,1249,1250],{"class":91,"line":132},[89,1251,1170],{"class":99},[36,1253,1255],{"id":1254},"发布订阅","发布\u002F订阅",[79,1257,1259],{"className":687,"code":1258,"language":689,"meta":84,"style":84},"\u002F\u002F 发布者\nawait redis.publish(\"notifications\", JSON.stringify({ type: \"new_message\" }));\n\n\u002F\u002F 订阅者\nconst sub = new Redis();\nsub.subscribe(\"notifications\");\nsub.on(\"message\", (channel, message) => {\n  console.log(channel, JSON.parse(message));\n});\n",[86,1260,1261,1266,1297,1301,1306,1321,1335,1367,1387],{"__ignoreMap":84},[89,1262,1263],{"class":91,"line":92},[89,1264,1265],{"class":186},"\u002F\u002F 发布者\n",[89,1267,1268,1270,1272,1275,1277,1280,1282,1284,1286,1288,1291,1294],{"class":91,"line":103},[89,1269,773],{"class":696},[89,1271,776],{"class":99},[89,1273,1274],{"class":212},"publish",[89,1276,782],{"class":99},[89,1278,1279],{"class":120},"\"notifications\"",[89,1281,788],{"class":99},[89,1283,1140],{"class":221},[89,1285,1084],{"class":99},[89,1287,1145],{"class":212},[89,1289,1290],{"class":99},"({ type: ",[89,1292,1293],{"class":120},"\"new_message\"",[89,1295,1296],{"class":99}," }));\n",[89,1298,1299],{"class":91,"line":111},[89,1300,237],{"emptyLinePlaceholder":236},[89,1302,1303],{"class":91,"line":124},[89,1304,1305],{"class":186},"\u002F\u002F 订阅者\n",[89,1307,1308,1310,1313,1315,1317,1319],{"class":91,"line":132},[89,1309,718],{"class":696},[89,1311,1312],{"class":221}," sub",[89,1314,724],{"class":696},[89,1316,727],{"class":696},[89,1318,730],{"class":212},[89,1320,933],{"class":99},[89,1322,1323,1326,1329,1331,1333],{"class":91,"line":141},[89,1324,1325],{"class":99},"sub.",[89,1327,1328],{"class":212},"subscribe",[89,1330,782],{"class":99},[89,1332,1279],{"class":120},[89,1334,794],{"class":99},[89,1336,1337,1339,1342,1344,1347,1350,1353,1355,1358,1361,1364],{"class":91,"line":149},[89,1338,1325],{"class":99},[89,1340,1341],{"class":212},"on",[89,1343,782],{"class":99},[89,1345,1346],{"class":120},"\"message\"",[89,1348,1349],{"class":99},", (",[89,1351,1352],{"class":1029},"channel",[89,1354,788],{"class":99},[89,1356,1357],{"class":1029},"message",[89,1359,1360],{"class":99},") ",[89,1362,1363],{"class":696},"=>",[89,1365,1366],{"class":99}," {\n",[89,1368,1369,1372,1375,1378,1380,1382,1384],{"class":91,"line":157},[89,1370,1371],{"class":99},"  console.",[89,1373,1374],{"class":212},"log",[89,1376,1377],{"class":99},"(channel, ",[89,1379,1140],{"class":221},[89,1381,1084],{"class":99},[89,1383,1087],{"class":212},[89,1385,1386],{"class":99},"(message));\n",[89,1388,1389],{"class":91,"line":283},[89,1390,759],{"class":99},[36,1392,1393],{"id":1393},"参考链接",[36,1395,1396],{"id":1396},"推荐上手顺序",[1398,1399,1400,1403,1406,1409],"ol",{},[44,1401,1402],{},"学会字符串和过期时间",[44,1404,1405],{},"学会哈希和列表",[44,1407,1408],{},"理解缓存旁路（Cache-Aside）",[44,1410,1411],{},"再看发布订阅和更复杂模式",[36,1413,1414],{"id":1414},"常见问题",[74,1416,1418],{"id":1417},"redis-内存为什么一直涨","Redis 内存为什么一直涨",[22,1420,1421],{},"通常是键没有设置过期，或者缓存淘汰策略没有配合业务设计好。",[74,1423,1425],{"id":1424},"为什么明明用了缓存数据库压力还是很大","为什么明明用了缓存，数据库压力还是很大",[22,1427,1428],{},"可能是命中率不高、TTL 太短、热点键策略不对，或者更新后根本没正确失效。",[74,1430,1432],{"id":1431},"redis-能不能直接替代数据库","Redis 能不能直接替代数据库",[22,1434,1435],{},"个别场景可以做主存储，但对大多数业务系统来说，Redis 更适合做缓存和高频短时数据层。",[41,1437,1438,1446,1453,1461],{},[44,1439,1440,1445],{},[25,1441,1444],{"href":1442,"rel":1443},"https:\u002F\u002Fredis.io\u002Fdocs\u002F",[29],"Redis 文档"," — 官方文档",[44,1447,1448,1452],{},[25,1449,668],{"href":1450,"rel":1451},"https:\u002F\u002Fgithub.com\u002Fredis\u002Fioredis",[29]," — Node.js 客户端",[44,1454,1455,1460],{},[25,1456,1459],{"href":1457,"rel":1458},"https:\u002F\u002Fredis.io\u002Finsight\u002F",[29],"Redis Insight"," — GUI 工具",[44,1462,1463,1467],{},[25,1464,1466],{"href":1465},"\u002Fdocs\u002Fdocker-compose-recipes","Docker Compose 常用配置"," — 如果你要把 Redis 作为本地服务栈的一部分一起跑",[1469,1470,1471],"style",{},"html pre.shiki code .s9eBZ, html code.shiki .s9eBZ{--shiki-default:#22863A;--shiki-dark:#85E89D}html pre.shiki code .sVt8B, html code.shiki .sVt8B{--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .sZZnC, html code.shiki .sZZnC{--shiki-default:#032F62;--shiki-dark:#9ECBFF}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sJ8bj, html code.shiki .sJ8bj{--shiki-default:#6A737D;--shiki-dark:#6A737D}html pre.shiki code .sScJk, html code.shiki .sScJk{--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .sj4cs, html code.shiki .sj4cs{--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .szBVR, html code.shiki .szBVR{--shiki-default:#D73A49;--shiki-dark:#F97583}html pre.shiki code .s4XuR, html code.shiki .s4XuR{--shiki-default:#E36209;--shiki-dark:#FFAB70}",{"title":84,"searchDepth":103,"depth":103,"links":1473},[1474,1475,1476,1480,1481,1484,1488,1489,1490,1491],{"id":38,"depth":103,"text":39},{"id":58,"depth":103,"text":58},{"id":72,"depth":103,"text":72,"children":1477},[1478,1479],{"id":76,"depth":111,"text":77},{"id":168,"depth":111,"text":169},{"id":195,"depth":103,"text":195},{"id":664,"depth":103,"text":665,"children":1482},[1483],{"id":668,"depth":111,"text":668},{"id":1004,"depth":103,"text":1004,"children":1485},[1486,1487],{"id":1007,"depth":111,"text":1008},{"id":1173,"depth":111,"text":1173},{"id":1254,"depth":103,"text":1255},{"id":1393,"depth":103,"text":1393},{"id":1396,"depth":103,"text":1396},{"id":1414,"depth":103,"text":1414,"children":1492},[1493,1494,1495],{"id":1417,"depth":111,"text":1418},{"id":1424,"depth":111,"text":1425},{"id":1431,"depth":111,"text":1432},{"path":1497,"title":1498,"description":1499,"docType":8,"resourceKind":9,"categoryId":1500,"categoryLabel":1501,"updatedAt":12,"publishedAt":12,"icon":1502},"\u002Fdocs\u002Fpt-trackers","PT 站点与资源","私有 BT 追踪器站点汇总、公开索引与使用指南","entertainment-resources","娱乐与资源","i-carbon-game-console",{"path":1504,"title":1505,"description":1506,"docType":8,"resourceKind":9,"categoryId":1507,"categoryLabel":1508,"updatedAt":12,"publishedAt":12,"icon":1509},"\u002Fdocs\u002Fs3-storage","S3 对象存储","S3 兼容存储使用、Cloudflare R2、MinIO 自建、rclone 同步与 SDK 集成","infra-deployment","服务器与部署","i-carbon-cloud",[1511,1512,1513],"希望把零散经验整理成长期可复用工作流的人","想先建立认知，再决定是否深入实践的人","希望阅读时顺手建立自己的操作清单或收藏体系的人",[1515,1516,1517],"先浏览标题、摘要和目录，带着问题阅读会更高效","顺手记录真正对你有用的命令、链接和注意事项，避免重复搜索","如果页面里提到相关文档，尽量一起打开对照，效果通常更完整",[1519,1523,1527,1531],{"path":1520,"title":1521,"description":1522,"docType":8,"resourceKind":9,"categoryId":10,"categoryLabel":11,"updatedAt":12,"publishedAt":12,"icon":13},"\u002Fdocs\u002Ftesting-guide","前端测试指南","Vitest 单元测试、Playwright E2E 测试、测试策略与最佳实践",{"path":1524,"title":1525,"description":1526,"docType":8,"resourceKind":9,"categoryId":10,"categoryLabel":11,"updatedAt":12,"publishedAt":12,"icon":13},"\u002Fdocs\u002Fbun-deno","Bun 与 Deno 运行时","Bun 和 Deno 的安装使用、与 Node.js 对比、包管理与实用命令",{"path":1528,"title":1529,"description":1530,"docType":8,"resourceKind":9,"categoryId":10,"categoryLabel":11,"updatedAt":12,"publishedAt":12,"icon":13},"\u002Fdocs\u002Fcss-tricks","CSS 实用技巧","现代 CSS 特性、布局技巧、动画、暗色模式与常用代码片段",{"path":1532,"title":1533,"description":1534,"docType":8,"resourceKind":9,"categoryId":10,"categoryLabel":11,"updatedAt":1535,"publishedAt":1535,"icon":13},"\u002Fdocs\u002Fdatabase-basics","数据库基础速查","SQLite、PostgreSQL、MySQL 常用操作、SQL 语法与 GUI 工具推荐","2026-02-27",1776215714028]