[{"data":1,"prerenderedAt":5974},["ShallowReactive",2],{"search-docs":3,"doc-\u002Fgolang\u002Fdistributed\u002Fredis":886},[4,8,12,16,20,24,28,32,36,40,44,48,52,56,60,64,68,72,76,80,84,88,92,96,100,104,108,112,116,120,124,128,132,136,140,144,148,152,156,159,162,165,169,172,175,178,182,186,190,194,198,202,206,210,214,218,222,226,230,234,238,242,246,250,254,258,262,266,269,273,277,281,285,288,291,294,298,301,304,307,310,313,316,319,322,325,329,332,336,340,344,348,352,356,359,362,365,368,371,374,377,380,383,386,389,393,396,399,402,405,408,411,414,417,420,424,428,432,435,438,442,446,450,454,458,462,466,470,474,477,480,483,487,491,494,497,500,504,507,511,515,518,521,524,527,530,533,536,539,542,545,548,551,554,557,560,563,566,569,572,575,579,583,587,591,595,599,603,606,610,614,617,620,623,626,629,633,637,640,643,646,649,652,655,658,661,664,667,670,673,676,679,682,685,688,691,694,697,700,703,706,709,712,716,720,724,728,732,736,740,744,748,752,756,760,764,768,772,775,779,783,787,790,793,796,799,802,805,808,811,814,818,822,825,829,832,835,838,841,844,848,851,854,858,862,865,869,873,876,879,882],{"path":5,"title":6,"description":7},"\u002Fabout\u002Fauthor","作者相关","只想纯粹的做一个程序员...",{"path":9,"title":10,"description":11},"\u002Fabout\u002Fjourney","心路历程","",{"path":13,"title":14,"description":15},"\u002Fai\u002Fagent\u002Fframeworks","Agent 框架","主流 Agent 框架：LangChain、LlamaIndex、AutoGen、CrewAI",{"path":17,"title":18,"description":19},"\u002Fai\u002Fagent\u002Fhooks","Agent Hooks 与自动化","Claude Agent 的 Hooks 生命周期、事件类型、典型自动化场景",{"path":21,"title":22,"description":23},"\u002Fai\u002Fagent\u002Fintroduction","AI Agent 概述","AI Agent 核心概念：感知、规划、执行、记忆",{"path":25,"title":26,"description":27},"\u002Fai\u002Fagent\u002Fpractice","Agent 实战","AI Agent 实战：构建自主任务执行系统",{"path":29,"title":30,"description":31},"\u002Fai\u002Fagent\u002Fsdk","Claude Agent SDK 开发","使用 Claude Agent SDK 构建自定义 AI Agent：架构、API、生命周期",{"path":33,"title":34,"description":35},"\u002Fai\u002Fagent\u002Fsubagents","Subagents 子代理","用 Subagents 分解复杂任务、并发执行、隔离上下文",{"path":37,"title":38,"description":39},"\u002Fai\u002Fagent\u002Ftool-use","工具调用","AI Agent 工具调用：Function Calling、Tool Use 原理与实践",{"path":41,"title":42,"description":43},"\u002Fai\u002Ffundamentals\u002Fdeep-learning","深度学习入门","深度学习基础知识：前向传播、反向传播、损失函数、优化器",{"path":45,"title":46,"description":47},"\u002Fai\u002Ffundamentals\u002Fml-basics","机器学习基础","机器学习核心概念：监督学习、无监督学习、强化学习",{"path":49,"title":50,"description":51},"\u002Fai\u002Ffundamentals\u002Fneural-networks","神经网络原理","神经网络架构：CNN、RNN、注意力机制",{"path":53,"title":54,"description":55},"\u002Fai\u002Fgetting-started","AI 学习路线","AI 技术学习路线图，从基础到实战的完整指南",{"path":57,"title":58,"description":59},"\u002Fai\u002Fllm\u002Ffine-tuning","模型微调","大模型微调技术：LoRA、QLoRA、全量微调、RLHF",{"path":61,"title":62,"description":63},"\u002Fai\u002Fllm\u002Fintroduction","大模型概述","大语言模型发展历程、核心能力与主流模型对比",{"path":65,"title":66,"description":67},"\u002Fai\u002Fllm\u002Flocal-deploy","本地部署","大模型本地部署：Ollama、vLLM、llama.cpp",{"path":69,"title":70,"description":71},"\u002Fai\u002Fllm\u002Ftransformer","Transformer 架构","Transformer 架构详解：自注意力机制、位置编码、多头注意力",{"path":73,"title":74,"description":75},"\u002Fai\u002Fmcp\u002Fclient","MCP Client 开发","MCP Client 开发指南：连接、调用、集成",{"path":77,"title":78,"description":79},"\u002Fai\u002Fmcp\u002Fdebugging","MCP 调试与排错","MCP Server 开发与集成过程中的常见问题、日志分析、诊断工具",{"path":81,"title":82,"description":83},"\u002Fai\u002Fmcp\u002Fintroduction","MCP 概述","Model Context Protocol 协议概述：架构、核心概念、应用场景",{"path":85,"title":86,"description":87},"\u002Fai\u002Fmcp\u002Fserver","MCP Server 开发","MCP Server 开发指南：资源、工具、提示词的实现",{"path":89,"title":90,"description":91},"\u002Fai\u002Fmcp\u002Ftools","MCP Tools 深入","深入理解 MCP Tools：与 Resources\u002FPrompts 的差异、Schema 设计、Annotations 与权限控制",{"path":93,"title":94,"description":95},"\u002Fai\u002Fprompt\u002Fadvanced","高级 Prompt 模式","高级 Prompt 设计模式：Tree-of-Thought、自我反思、多轮对话策略",{"path":97,"title":98,"description":99},"\u002Fai\u002Fprompt\u002Fbasics","Prompt 基础","Prompt Engineering 入门：基本概念、角色设定、输出格式控制",{"path":101,"title":102,"description":103},"\u002Fai\u002Fprompt\u002Ftechniques","提示词技巧","常用提示词技巧：Few-shot、Chain-of-Thought、ReAct",{"path":105,"title":106,"description":107},"\u002Fai\u002Frag\u002Fembedding","文本嵌入","文本嵌入模型：Embedding 原理、模型选择、相似度计算",{"path":109,"title":110,"description":111},"\u002Fai\u002Frag\u002Fintroduction","RAG 概述","检索增强生成（RAG）架构原理、优势与应用场景",{"path":113,"title":114,"description":115},"\u002Fai\u002Frag\u002Fpractice","RAG 实战","RAG 应用实战：文档问答系统、知识库搭建",{"path":117,"title":118,"description":119},"\u002Fai\u002Frag\u002Fvector-database","向量数据库","主流向量数据库对比：Milvus、Pinecone、Chroma、Weaviate",{"path":121,"title":122,"description":123},"\u002Fai\u002Fskills\u002Fbest-practices","Skill 最佳实践","编写高质量 Skill 的设计原则、常见陷阱与优化技巧",{"path":125,"title":126,"description":127},"\u002Fai\u002Fskills\u002Fcreating","创建自定义 Skill","从零编写一个可被 Agent 自动发现和调用的 Skill",{"path":129,"title":130,"description":131},"\u002Fai\u002Fskills\u002Fintroduction","Agent Skills 概述","Claude Agent Skills 概念、工作原理、与 Tools\u002FMCP 的区别",{"path":133,"title":134,"description":135},"\u002Fgolang\u002Fadvanced\u002Fconcurrency","Go - 并发深入","深入理解 Go 并发编程的核心机制。",{"path":137,"title":138,"description":139},"\u002Fgolang\u002Fadvanced\u002Fgc","Go - 垃圾回收","理解 Go 的垃圾回收机制，掌握 GC 调优方法。",{"path":141,"title":142,"description":143},"\u002Fgolang\u002Fadvanced\u002Fgmp","Go - GMP 调度模型","GMP 是 Go 运行时调度器的核心模型，理解它对于编写高性能 Go 程序至关重要。",{"path":145,"title":146,"description":147},"\u002Fgolang\u002Fadvanced\u002Fgo-concurrency","Go - 并发编程","Go 的并发是其核心特性之一，通过 Goroutine 和 Channel 实现。",{"path":149,"title":150,"description":151},"\u002Fgolang\u002Fadvanced\u002Fmemory","Go - 内存模型","理解 Go 的内存分配机制和内存模型。",{"path":153,"title":154,"description":155},"\u002Fgolang\u002Fadvanced\u002Fprofiling","Go - 性能分析","掌握 Go 的性能分析工具：pprof、trace、benchmark。",{"path":157,"title":158,"description":11},"\u002Fgolang\u002Fcore\u002Fgo-basic","Go - 基础语法",{"path":160,"title":161,"description":11},"\u002Fgolang\u002Fcore\u002Fgo-composite","Go - 复合类型",{"path":163,"title":164,"description":11},"\u002Fgolang\u002Fcore\u002Fgo-control","Go - 流程控制",{"path":166,"title":167,"description":168},"\u002Fgolang\u002Fcore\u002Fgo-error","Go - 错误处理","Go 使用显式的错误返回值来处理错误，而不是异常机制。",{"path":170,"title":171,"description":11},"\u002Fgolang\u002Fcore\u002Fgo-function","Go - 函数",{"path":173,"title":174,"description":11},"\u002Fgolang\u002Fcore\u002Fgo-install","Go - 环境搭建",{"path":176,"title":177,"description":11},"\u002Fgolang\u002Fcore\u002Fgo-interface","Go - 接口",{"path":179,"title":180,"description":181},"\u002Fgolang\u002Fcore\u002Fgo-module","Go - 包管理","Go Modules 是 Go 1.11 引入的官方依赖管理方案，Go 1.16 后成为默认模式。",{"path":183,"title":184,"description":185},"\u002Fgolang\u002Fdistributed\u002Fgrpc","Go - gRPC","gRPC 是 Google 开发的高性能 RPC 框架，使用 Protocol Buffers 作为序列化协议。",{"path":187,"title":188,"description":189},"\u002Fgolang\u002Fdistributed\u002Fmicroservice","Go - 微服务","微服务架构的核心组件：服务发现、负载均衡、熔断降级。",{"path":191,"title":192,"description":193},"\u002Fgolang\u002Fdistributed\u002Fmq","Go - 消息队列","使用 Go 操作 Kafka 和 RabbitMQ。",{"path":195,"title":196,"description":197},"\u002Fgolang\u002Fdistributed\u002Fredis","Go - Redis","使用 go-redis 操作 Redis，实现缓存、分布式锁等功能。",{"path":199,"title":200,"description":201},"\u002Fgolang\u002Fengineering\u002Fconfig","Go - 配置管理","使用 viper 进行配置管理，支持多种配置格式和配置中心。",{"path":203,"title":204,"description":205},"\u002Fgolang\u002Fengineering\u002Fdocker","Go - Docker 部署","使用 Docker 容器化部署 Go 应用。",{"path":207,"title":208,"description":209},"\u002Fgolang\u002Fengineering\u002Fkubernetes","Go - Kubernetes 部署","在 Kubernetes 上部署和管理 Go 应用。",{"path":211,"title":212,"description":213},"\u002Fgolang\u002Fengineering\u002Flogging","Go - 日志系统","使用 zap 和 logrus 构建高性能结构化日志系统。",{"path":215,"title":216,"description":217},"\u002Fgolang\u002Fengineering\u002Ftesting","Go - 单元测试","Go 内置了强大的测试框架，掌握测试是编写高质量代码的基础。",{"path":219,"title":220,"description":221},"\u002Fgolang\u002Fstdlib\u002Fbufio","bufio","在 Go 语言中，bufio 包提供了带缓冲的 I\u002FO 操作，能够提高读写性能。以下是一些常用的 bufio 包 API 及其详细说明：",{"path":223,"title":224,"description":225},"\u002Fgolang\u002Fstdlib\u002Fcontainer","container","在Go语言标准库中，container 包提供了几种常用的数据结构实现，这些数据结构对于高效地管理和操作数据非常有用。以下是 container 包中主要的数据结构：",{"path":227,"title":228,"description":229},"\u002Fgolang\u002Fstdlib\u002Fcrypto","crypto","在 Go 语言中，crypto 包提供了一组用于加密和解密的功能。以下是一些常用的 crypto 包及其子包的 API 及其详细说明：",{"path":231,"title":232,"description":233},"\u002Fgolang\u002Fstdlib\u002Fencoding-csv","encoding\u002Fcsv","在 Go 语言中，encoding\u002Fcsv 包提供了对 CSV（逗号分隔值）文件进行读写的功能。以下是一些常用的 encoding\u002Fcsv 包的 API 及其详细说明：",{"path":235,"title":236,"description":237},"\u002Fgolang\u002Fstdlib\u002Fencoding-json","encoding\u002Fjson","在 Go 语言中，encoding\u002Fjson 包提供了对 JSON 数据进行编码和解码的功能。以下是一些常用的 encoding\u002Fjson 包的 API 及其详细说明：",{"path":239,"title":240,"description":241},"\u002Fgolang\u002Fstdlib\u002Fencoding-xml","encoding\u002Fxml","在 Go 语言中，encoding\u002Fxml 包提供了对 XML 数据进行编码和解码的功能。以下是一些常用的 encoding\u002Fxml 包的 API 及其详细说明：",{"path":243,"title":244,"description":245},"\u002Fgolang\u002Fstdlib\u002Fflag","flag","在Go语言中，flag 包是用于处理命令行参数的标准库，它提供了一种简单而直接的方式来解析和使用命令行参数。下面是关于 flag 包的一些基本介绍和常用功能：",{"path":247,"title":248,"description":249},"\u002Fgolang\u002Fstdlib\u002Ffmt","fmt","在 Go 语言的标准库中，fmt 包是非常重要的，它提供了处理格式化输入和输出的基本工具。以下是一些 fmt 包内常用的API：",{"path":251,"title":252,"description":253},"\u002Fgolang\u002Fstdlib\u002Fhttp","net\u002Fhttp","在 Go 语言中，net\u002Fhttp 包提供了用于构建 HTTP 客户端和服务器的强大工具。以下是一些常用的 net\u002Fhttp 包的 API 及其详细说明：",{"path":255,"title":256,"description":257},"\u002Fgolang\u002Fstdlib\u002Fio","io","在 Go 语言中，io 包提供了基本的输入输出功能。以下是一些常用的 io 包的 API 及其详细说明：",{"path":259,"title":260,"description":261},"\u002Fgolang\u002Fstdlib\u002Flog","log","在 Go 语言中，log 包提供了简单的日志记录功能。以下是一些常用的 log 包的 API 及其详细说明：",{"path":263,"title":264,"description":265},"\u002Fgolang\u002Fstdlib\u002Fmath","math","在 Go 语言中，math 包提供了基本的数学函数和常量。以下是一些常用的 math 包的 API 及其详细说明：",{"path":267,"title":268,"description":11},"\u002Fgolang\u002Fstdlib\u002Fnet","net",{"path":270,"title":271,"description":272},"\u002Fgolang\u002Fstdlib\u002Fos","os","在Go语言中，os 包是一个非常重要且常用的标准库，它提供了与操作系统交互的功能，包括文件操作、环境变量管理、进程管理等。下面是一些 os 包中常用的功能和API：",{"path":274,"title":275,"description":276},"\u002Fgolang\u002Fstdlib\u002Fsort","order","在 Go 语言中，sort 包提供了对切片和用户定义的集合进行排序的函数。它实现了常见的排序算法，如快速排序（Quicksort）和堆排序（Heapsort），并且为自定义集合提供了接口，使得用户可以根据特定的需求进行排序。",{"path":278,"title":279,"description":280},"\u002Fgolang\u002Fstdlib\u002Fstrconv","strconv","在 Go 语言中，strconv 包提供了字符串和基本数据类型之间的转换函数，例如将整数转换为字符串、字符串转换为整数，以及其他类型之间的转换。这些功能非常有用，特别是在处理用户输入或从外部数据源读取数据时。",{"path":282,"title":283,"description":284},"\u002Fgolang\u002Fstdlib\u002Ftime","time","在 Go 语言中，time 包提供了处理时间和日期的功能。以下是一些常用的 time 包的 API 及其详细说明：",{"path":286,"title":287,"description":11},"\u002Fgolang\u002Fweb\u002Fgin\u002Ferror","Gin - 错误处理",{"path":289,"title":290,"description":11},"\u002Fgolang\u002Fweb\u002Fgin\u002Ffile","Gin - 文件处理",{"path":292,"title":293,"description":11},"\u002Fgolang\u002Fweb\u002Fgin\u002Fmiddleware","Gin - 中间件",{"path":295,"title":296,"description":297},"\u002Fgolang\u002Fweb\u002Fgin\u002Fquickstart","Gin - 快速开始","Gin 是目前最流行的 Go Web 框架，以高性能和简洁 API 著称。",{"path":299,"title":300,"description":11},"\u002Fgolang\u002Fweb\u002Fgin\u002Frequest","Gin - 请求处理",{"path":302,"title":303,"description":11},"\u002Fgolang\u002Fweb\u002Fgin\u002Fresponse","Gin - 响应处理",{"path":305,"title":306,"description":11},"\u002Fgolang\u002Fweb\u002Fgin\u002Frouter","Gin - 路由",{"path":308,"title":309,"description":11},"\u002Fgolang\u002Fweb\u002Fgin\u002Fvalidation","Gin - 参数校验",{"path":311,"title":312,"description":11},"\u002Fgolang\u002Fweb\u002Fgorm\u002Fassociation","GORM - 关联关系",{"path":314,"title":315,"description":11},"\u002Fgolang\u002Fweb\u002Fgorm\u002Fcrud","GORM - CRUD 操作",{"path":317,"title":318,"description":11},"\u002Fgolang\u002Fweb\u002Fgorm\u002Fmodel","GORM - 模型定义",{"path":320,"title":321,"description":11},"\u002Fgolang\u002Fweb\u002Fgorm\u002Fperformance","GORM - 日志与性能",{"path":323,"title":324,"description":11},"\u002Fgolang\u002Fweb\u002Fgorm\u002Fquery","GORM - 高级查询",{"path":326,"title":327,"description":328},"\u002Fgolang\u002Fweb\u002Fgorm\u002Fquickstart","GORM - 快速开始","GORM 是 Go 语言最流行的 ORM 库，功能强大，使用简单。",{"path":330,"title":331,"description":11},"\u002Fgolang\u002Fweb\u002Fgorm\u002Ftransaction","GORM - 事务与 Hook",{"path":333,"title":334,"description":335},"\u002Finterview\u002Fbasic","计算机基础面经","本章节汇总了面试中常见的通用技术概念，不局限于特定语言或数据库，是考察技术内功的关键考点。",{"path":337,"title":338,"description":339},"\u002Finterview\u002Fgolang","Golang 面试题","Go 语言面试高频考点，覆盖基础语法、数据结构、并发编程、内存管理、GC、调度器等核心知识。",{"path":341,"title":342,"description":343},"\u002Finterview\u002Fk8s","Kubernetes 面试题","Kubernetes（K8s）面试高频考点，覆盖架构原理、核心资源、网络存储、调度策略、运维监控等核心知识。",{"path":345,"title":346,"description":347},"\u002Finterview\u002Fmysql","MySQL 面试题","MySQL 数据库面试高频考点，覆盖索引、事务、锁、优化、主从复制等核心知识。",{"path":349,"title":350,"description":351},"\u002Finterview\u002Fredis","Redis 面试题","Redis 面试高频考点，覆盖数据结构、持久化、集群、缓存一致性、性能优化等核心知识。",{"path":353,"title":354,"description":355},"\u002Finterview\u002Frocketmq","RocketMQ 面试题","RocketMQ 面试高频考点，覆盖消息模型、可靠性、顺序消息、事务消息、存储与高可用等核心知识。",{"path":357,"title":358,"description":11},"\u002Fother\u002Fjava\u002Fcollection\u002Flist-arraylist","List - ArrayList 源码解析",{"path":360,"title":361,"description":11},"\u002Fother\u002Fjava\u002Fcollection\u002Flist-linkedlist","List - LinkedList 源码解析",{"path":363,"title":364,"description":11},"\u002Fother\u002Fjava\u002Fcollection\u002Flist-stack","List - Satck源码解析",{"path":366,"title":367,"description":11},"\u002Fother\u002Fjava\u002Fcollection\u002Flist-vectore","List - Vector 源码解析",{"path":369,"title":370,"description":11},"\u002Fother\u002Fjava\u002Fcollection\u002Fmap-hashmap","Map - HashMap 源码解析",{"path":372,"title":373,"description":11},"\u002Fother\u002Fjava\u002Fcollection\u002Fmap-linkedhashmap","Map - LinkedHashMap 源码解析",{"path":375,"title":376,"description":11},"\u002Fother\u002Fjava\u002Fcollection\u002Fmap-treemap","Map - TreeMap 源码解析",{"path":378,"title":379,"description":11},"\u002Fother\u002Fjava\u002Fcollection\u002Fqueue-deque","Queue - Deque 接口解析",{"path":381,"title":382,"description":11},"\u002Fother\u002Fjava\u002Fcollection\u002Fqueue-queue","Queue - Queue 接口解析",{"path":384,"title":385,"description":11},"\u002Fother\u002Fjava\u002Fcollection\u002Fset-hashset","Set - HashSet源码解析",{"path":387,"title":388,"description":11},"\u002Fother\u002Fjava\u002Fcollection\u002Fset-linkedhashset","Set - LinkedHashSet 源码解析",{"path":390,"title":391,"description":392},"\u002Fother\u002Fjava\u002Fcollection\u002Fset-treeset","Set - TreeSet源码解析","TreeSet 是一个 Set 集合接口的实现类，与 HashSet 类似，其底层也是通过维护了一个 TreeMap 对象来封装了一些实现方法，故本篇不再对 TreeSet 的底层原理进行详细说明，仅对常用 API 做简单介绍，如需了解 TreeMap 的底层实现原理，请移步 Map - HashMap 源码解析",{"path":394,"title":395,"description":11},"\u002Fother\u002Fjava\u002Fcore\u002Fannotation","Java核心 - 注解",{"path":397,"title":398,"description":11},"\u002Fother\u002Fjava\u002Fcore\u002Fbasic-grammar","Java核心 - 基础语法",{"path":400,"title":401,"description":11},"\u002Fother\u002Fjava\u002Fcore\u002Fclass-and-object","Java核心 - 面向对象",{"path":403,"title":404,"description":11},"\u002Fother\u002Fjava\u002Fcore\u002Fcommon-classes","Java核心 - 常用类",{"path":406,"title":407,"description":11},"\u002Fother\u002Fjava\u002Fcore\u002Fexception","Java核心 - 异常处理",{"path":409,"title":410,"description":11},"\u002Fother\u002Fjava\u002Fcore\u002Fgenerics","Java核心 - 泛型",{"path":412,"title":413,"description":11},"\u002Fother\u002Fjava\u002Fcore\u002Fjdk-env-path","Java核心 - 环境搭建",{"path":415,"title":416,"description":11},"\u002Fother\u002Fjava\u002Fcore\u002Freflection","Java核心 - 反射",{"path":418,"title":419,"description":11},"\u002Fother\u002Fjava\u002Fcore\u002Fstring","Java核心 - String 字符串",{"path":421,"title":422,"description":423},"\u002Fother\u002Fjava\u002Fio\u002Fbuffer-stream","Java IO - 缓冲流","缓冲流是对基本流的包装，通过内置缓冲区减少系统调用次数，大幅提升读写效率。",{"path":425,"title":426,"description":427},"\u002Fother\u002Fjava\u002Fio\u002Fbyte-stream","Java IO - 字节流","字节流是 Java IO 中最基本的流类型，以字节（byte）为单位进行数据读写，可以处理任意类型的文件。",{"path":429,"title":430,"description":431},"\u002Fother\u002Fjava\u002Fio\u002Fchar-stream","Java IO - 字符流","字符流以字符为单位进行读写，专门用于处理文本文件。相比字节流，字符流能够正确处理字符编码，避免中文乱码问题。",{"path":433,"title":434,"description":11},"\u002Fother\u002Fjava\u002Fio\u002Ffile","Java IO - File 类",{"path":436,"title":437,"description":11},"\u002Fother\u002Fjava\u002Fio\u002Fio-stream-system","Java IO - IO流概述",{"path":439,"title":440,"description":441},"\u002Fother\u002Fjava\u002Fio\u002Fnio","Java IO - NIO","NIO（New IO）是 JDK 1.4 引入的新 IO 模型，提供了更高效的 IO 操作方式，支持非阻塞 IO 和多路复用。",{"path":443,"title":444,"description":445},"\u002Fother\u002Fjava\u002Fjvm\u002Fclass-loading","类加载机制","类加载机制是 JVM 将 .class 文件加载到内存，并对数据进行校验、转换解析和初始化，最终形成可被 JVM 直接使用的 Java 类型的过程。",{"path":447,"title":448,"description":449},"\u002Fother\u002Fjava\u002Fjvm\u002Fgarbage-collection","垃圾回收","垃圾回收（Garbage Collection，GC）是 JVM 自动管理内存的机制，负责回收不再使用的对象所占用的内存。",{"path":451,"title":452,"description":453},"\u002Fother\u002Fjava\u002Fjvm\u002Fjvm-memory","JVM 内存结构","JVM 在执行 Java 程序时，会把它管理的内存划分为若干个不同的数据区域。这些区域有各自的用途、创建和销毁时间。",{"path":455,"title":456,"description":457},"\u002Fother\u002Fjava\u002Fjvm\u002Fjvm-tuning","JVM 调优","JVM 调优是优化 Java 应用性能的重要手段，主要包括参数配置、性能监控和问题排查。",{"path":459,"title":460,"description":461},"\u002Fother\u002Fjava\u002Fthread\u002Fatomic","原子类","Java 原子类（Atomic Classes）提供了一种无锁的线程安全方式，基于 CAS（Compare-And-Swap）操作实现。",{"path":463,"title":464,"description":465},"\u002Fother\u002Fjava\u002Fthread\u002Fcompletable-future","CompletableFuture","CompletableFuture 是 JDK 8 引入的异步编程工具，实现了 Future 和 CompletionStage 接口，支持函数式编程和链式调用。",{"path":467,"title":468,"description":469},"\u002Fother\u002Fjava\u002Fthread\u002Fconcurrent-collections","并发集合","Java 并发包提供了多种线程安全的集合类，用于替代传统的同步集合（如 Collections.synchronizedList）。",{"path":471,"title":472,"description":473},"\u002Fother\u002Fjava\u002Fthread\u002Fconcurrent-utils","并发工具类","Java 并发包提供了多种实用的并发工具类，用于控制线程之间的协调与同步。",{"path":475,"title":476,"description":11},"\u002Fother\u002Fjava\u002Fthread\u002Fsynchronized-lock","同步机制",{"path":478,"title":479,"description":11},"\u002Fother\u002Fjava\u002Fthread\u002Fthread-basic","线程基础",{"path":481,"title":482,"description":11},"\u002Fother\u002Fjava\u002Fthread\u002Fthread-pool","线程池",{"path":484,"title":485,"description":486},"\u002Fother\u002Fspring-series\u002Fspring\u002Fannotations-beans","Spring - 基于注解管理Bean","从 Java 5 开始，Java 增加了对注解（Annotation）的支持，它是代码中的一种特殊标记，可以在编译、类加载和运行时被读取，执行相应的处理。开发人员可以通过注解在不改变原有代码和逻辑的情况下，在源代码中嵌入补充信息。",{"path":488,"title":489,"description":490},"\u002Fother\u002Fspring-series\u002Fspring\u002Fimplement-ioc","Spring - 原理手写IoC","Spring 框架的 IOC 是基于 Java 反射机制实现的，在学习手写 IoC 之前，你需要具备一定的 Java 反射相关的知识，参考本站内的 Java 教程。",{"path":492,"title":493,"description":11},"\u002Fother\u002Fspring-series\u002Fspring\u002Fintroduction-case","Spring - 入门案例",{"path":495,"title":496,"description":11},"\u002Fother\u002Fspring-series\u002Fspring\u002Fspring-aop","Spring - 面向切面AOP",{"path":498,"title":499,"description":11},"\u002Fother\u002Fspring-series\u002Fspring\u002Fspring-aot","Spring - AOT提前编译",{"path":501,"title":502,"description":503},"\u002Fother\u002Fspring-series\u002Fspring\u002Fspring-data-validation","Spring - 数据校验","在开发中，我们经常遇到参数校验的需求，比如用户注册的时候，要校验用户名不能为空、用户名长度不超过20个字符、手机号是合法的手机号格式等等。如果使用普通方式，我们会把校验的代码和真正的业务处理逻辑耦合在一起，而且如果未来要新增一种校验逻辑也需要在修改多个地方。而spring validation允许通过注解的方式来定义对象校验规则，把校验和业务逻辑分离开，让代码编写更加方便。Spring Validation其实就是对Hibernate Validator进一步的封装，方便在Spring中使用。",{"path":505,"title":506,"description":11},"\u002Fother\u002Fspring-series\u002Fspring\u002Fspring-i18n","Spring - 国际化i18n",{"path":508,"title":509,"description":510},"\u002Fother\u002Fspring-series\u002Fspring\u002Fspring-ioc","Spring - IOC容器","IoC 是 Inversion of Control 的简写，译为“控制反转”，它不是一门技术，而是一种设计思想，是一个重要的面向对象编程法则，能够指导我们如何设计出松耦合、更优良的程序。",{"path":512,"title":513,"description":514},"\u002Fother\u002Fspring-series\u002Fspring\u002Fspring-junit","Spring - 单元测试JUnit","在之前的测试方法中，几乎都能看到以下的两行代码：",{"path":516,"title":517,"description":11},"\u002Fother\u002Fspring-series\u002Fspring\u002Fspring-resources","Spring - 资源操作",{"path":519,"title":520,"description":11},"\u002Fother\u002Fspring-series\u002Fspring\u002Fspring-summarize","Spring - Spring概述",{"path":522,"title":523,"description":11},"\u002Fother\u002Fspring-series\u002Fspring\u002Fspring-transaction","Spring - 事务",{"path":525,"title":526,"description":11},"\u002Fother\u002Fspring-series\u002Fspring\u002Fxml-beans","Spring - 基于XML管理Bean",{"path":528,"title":529,"description":11},"\u002Fother\u002Fspring-series\u002Fspringboot\u002Fspringboot-config","SpringBoot - 配置详解",{"path":531,"title":532,"description":11},"\u002Fother\u002Fspring-series\u002Fspringboot\u002Fspringboot-data","SpringBoot - 数据访问",{"path":534,"title":535,"description":11},"\u002Fother\u002Fspring-series\u002Fspringboot\u002Fspringboot-quickstart","SpringBoot - 快速入门",{"path":537,"title":538,"description":11},"\u002Fother\u002Fspring-series\u002Fspringboot\u002Fspringboot-web","SpringBoot - Web 开发",{"path":540,"title":541,"description":11},"\u002Fother\u002Fspring-series\u002Fspringcloud\u002Fspringcloud-config","SpringCloud - 配置中心",{"path":543,"title":544,"description":11},"\u002Fother\u002Fspring-series\u002Fspringcloud\u002Fspringcloud-discovery","SpringCloud - 服务注册与发现",{"path":546,"title":547,"description":11},"\u002Fother\u002Fspring-series\u002Fspringcloud\u002Fspringcloud-feign","SpringCloud - 服务调用",{"path":549,"title":550,"description":11},"\u002Fother\u002Fspring-series\u002Fspringcloud\u002Fspringcloud-gateway","SpringCloud - 服务网关",{"path":552,"title":553,"description":11},"\u002Fother\u002Fspring-series\u002Fspringcloud\u002Fspringcloud-introduction","SpringCloud - 微服务概述",{"path":555,"title":556,"description":11},"\u002Fother\u002Fspring-series\u002Fspringcloud\u002Fspringcloud-sentinel","SpringCloud - 服务保护",{"path":558,"title":559,"description":11},"\u002Fother\u002Fspring-series\u002Fspringmvc\u002Fspringmvc-databind","SpringMVC - 数据绑定与转换",{"path":561,"title":562,"description":11},"\u002Fother\u002Fspring-series\u002Fspringmvc\u002Fspringmvc-exception","SpringMVC - 异常处理",{"path":564,"title":565,"description":11},"\u002Fother\u002Fspring-series\u002Fspringmvc\u002Fspringmvc-interceptor","SpringMVC - 拦截器",{"path":567,"title":568,"description":11},"\u002Fother\u002Fspring-series\u002Fspringmvc\u002Fspringmvc-introduction","SpringMVC - 简介与环境搭建",{"path":570,"title":571,"description":11},"\u002Fother\u002Fspring-series\u002Fspringmvc\u002Fspringmvc-request","SpringMVC - 请求处理",{"path":573,"title":574,"description":11},"\u002Fother\u002Fspring-series\u002Fspringmvc\u002Fspringmvc-response","SpringMVC - 响应处理",{"path":576,"title":577,"description":578},"\u002Fproject\u002Frocket-leaf\u002Farchitecture","项目架构","Rocket-Leaf 的目录结构、模块划分、数据流向，以及各层之间的依赖关系。",{"path":580,"title":581,"description":582},"\u002Fproject\u002Frocket-leaf\u002Fbackend-layers","后端分层设计","Rocket-Leaf 的 model \u002F rocketmq \u002F service 三层结构，以及服务之间的依赖关系与设计取舍。",{"path":584,"title":585,"description":586},"\u002Fproject\u002Frocket-leaf\u002Fclient-manager","RocketMQ 客户端管理器","AdminClientManager 的多客户端池、默认连接懒加载、自动重连重试的设计与实现。",{"path":588,"title":589,"description":590},"\u002Fproject\u002Frocket-leaf\u002Fencryption","连接信息加密存储","AES-256-GCM + SHA-256 字段级派生密钥的实现，以及如何在不破坏兼容性的前提下为历史明文数据做透明迁移。",{"path":592,"title":593,"description":594},"\u002Fproject\u002Frocket-leaf\u002Ffrontend","前端结构与类型绑定","React + Vite 目录组织、自动生成的 Wails 绑定、api 薄封装与自定义 hooks 的职责划分。",{"path":596,"title":597,"description":598},"\u002Fproject\u002Frocket-leaf","项目简介","Rocket-Leaf 是一款基于 Wails v3 构建的跨平台 RocketMQ 桌面管理客户端，Go 后端 + React 前端。本文档系列拆解它的架构与关键实现。",{"path":600,"title":601,"description":602},"\u002Fproject\u002Frocket-leaf\u002Fwails-v3","Wails v3 入门","Wails v3 的核心概念、Service 绑定机制，以及 Rocket-Leaf 是如何用它把 Go 后端和 React 前端打通的。",{"path":604,"title":605,"description":11},"\u002Ftutorials\u002Fcloud\u002Fdocker\u002Fdocker-basic","Docker - 入门基础",{"path":607,"title":608,"description":609},"\u002Ftutorials\u002Fcloud\u002Fdocker\u002Fdocker-compose","Docker - Compose","在部署应用时，常常使用到不止一个容器，那么在部署容器的时候就需要一个一个进行部署，这样的部署过程也相对来说比较繁琐复杂，也容易出问题，那么有没有一种更为简单的方法呢？",{"path":611,"title":612,"description":613},"\u002Ftutorials\u002Fcloud\u002Fdocker\u002Fdocker-container-connection","Docker - 容器互联","在上一个章节中我们学习了 Docker 容器的端口映射，可以将 Docker 容器和本地以及网络中的端口进行连接起来。",{"path":615,"title":616,"description":11},"\u002Ftutorials\u002Fcloud\u002Fdocker\u002Fdocker-dockerfile","Docker - Dockerfile",{"path":618,"title":619,"description":11},"\u002Ftutorials\u002Fcloud\u002Fdocker\u002Fdocker-helloworld","Docker - HelloWorld",{"path":621,"title":622,"description":11},"\u002Ftutorials\u002Fcloud\u002Fdocker\u002Fdocker-install","Docker - 安装",{"path":624,"title":625,"description":11},"\u002Ftutorials\u002Fcloud\u002Fdocker\u002Fdocker-introduce","Docker - 简介",{"path":627,"title":628,"description":11},"\u002Ftutorials\u002Fcloud\u002Fdocker\u002Fdocker-object","Docker - 镜像、容器、仓库",{"path":630,"title":631,"description":632},"\u002Ftutorials\u002Fcloud\u002Fdocker\u002Fdocker-warehouse","Docker - 仓库管理","仓库是集中存放资源的地方，代码仓库是存放代码的，那么Docker 中的仓库就是存放 Docker 镜像的。",{"path":634,"title":635,"description":636},"\u002Ftutorials\u002Fcloud\u002Fdocker\u002Fdocker-web-containers","Docker - WEB应用实例","在之前的章节中，仅对普通容器进行了演示，但在实际中常常使用到 Docker 容器中的 WEB 应用程序。",{"path":638,"title":639,"description":11},"\u002Ftutorials\u002Fcloud\u002Fkubernetes\u002Fk8s-config","Kubernetes - ConfigMap 与 Secret",{"path":641,"title":642,"description":11},"\u002Ftutorials\u002Fcloud\u002Fkubernetes\u002Fk8s-helm","Kubernetes - Helm 包管理",{"path":644,"title":645,"description":11},"\u002Ftutorials\u002Fcloud\u002Fkubernetes\u002Fk8s-install","Kubernetes - 集群安装",{"path":647,"title":648,"description":11},"\u002Ftutorials\u002Fcloud\u002Fkubernetes\u002Fk8s-introduction","Kubernetes - 简介与架构",{"path":650,"title":651,"description":11},"\u002Ftutorials\u002Fcloud\u002Fkubernetes\u002Fk8s-kubectl","Kubernetes - kubectl 命令行工具",{"path":653,"title":654,"description":11},"\u002Ftutorials\u002Fcloud\u002Fkubernetes\u002Fk8s-monitoring","Kubernetes - 监控与日志",{"path":656,"title":657,"description":11},"\u002Ftutorials\u002Fcloud\u002Fkubernetes\u002Fk8s-network-security","Kubernetes - 网络与安全",{"path":659,"title":660,"description":11},"\u002Ftutorials\u002Fcloud\u002Fkubernetes\u002Fk8s-service","Kubernetes - Service 与 Ingress",{"path":662,"title":663,"description":11},"\u002Ftutorials\u002Fcloud\u002Fkubernetes\u002Fk8s-storage","Kubernetes - 持久化存储",{"path":665,"title":666,"description":11},"\u002Ftutorials\u002Fcloud\u002Fkubernetes\u002Fk8s-workload","Kubernetes - 工作负载资源",{"path":668,"title":669,"description":11},"\u002Ftutorials\u002Fcloud\u002Flinux\u002Flinux-bash","Linux - Bash 基础语法",{"path":671,"title":672,"description":11},"\u002Ftutorials\u002Fcloud\u002Flinux\u002Flinux-file-directory","Linux - 文件与目录操作",{"path":674,"title":675,"description":11},"\u002Ftutorials\u002Fcloud\u002Flinux\u002Flinux-network","Linux - 网络配置",{"path":677,"title":678,"description":11},"\u002Ftutorials\u002Fcloud\u002Flinux\u002Flinux-package","Linux - 软件包管理",{"path":680,"title":681,"description":11},"\u002Ftutorials\u002Fcloud\u002Flinux\u002Flinux-process","Linux - 进程管理",{"path":683,"title":684,"description":11},"\u002Ftutorials\u002Fcloud\u002Flinux\u002Flinux-scripts","Linux - 常用脚本示例",{"path":686,"title":687,"description":11},"\u002Ftutorials\u002Fcloud\u002Flinux\u002Flinux-service","Linux - 服务管理",{"path":689,"title":690,"description":11},"\u002Ftutorials\u002Fcloud\u002Flinux\u002Flinux-user-permission","Linux - 用户与权限管理",{"path":692,"title":693,"description":11},"\u002Ftutorials\u002Fcloud\u002Fnginx\u002Fnginx-https","Nginx - HTTPS 配置",{"path":695,"title":696,"description":11},"\u002Ftutorials\u002Fcloud\u002Fnginx\u002Fnginx-install","Nginx - 安装与配置",{"path":698,"title":699,"description":11},"\u002Ftutorials\u002Fcloud\u002Fnginx\u002Fnginx-loadbalance","Nginx - 负载均衡",{"path":701,"title":702,"description":11},"\u002Ftutorials\u002Fcloud\u002Fnginx\u002Fnginx-optimization","Nginx - 性能优化",{"path":704,"title":705,"description":11},"\u002Ftutorials\u002Fcloud\u002Fnginx\u002Fnginx-proxy","Nginx - 反向代理",{"path":707,"title":708,"description":11},"\u002Ftutorials\u002Fcloud\u002Fnginx\u002Fnginx-static","Nginx - 静态资源服务",{"path":710,"title":711,"description":11},"\u002Ftutorials\u002Fcloud\u002Fnginx\u002Fnginx-vhost","Nginx - 虚拟主机配置",{"path":713,"title":714,"description":715},"\u002Ftutorials\u002Fdatabase\u002Fmysql\u002Fmysql-architecture","MySQL 高可用架构","主从复制、读写分离、分库分表。",{"path":717,"title":718,"description":719},"\u002Ftutorials\u002Fdatabase\u002Fmysql\u002Fmysql-index","MySQL 索引","索引是帮助 MySQL 高效获取数据的有序数据结构。",{"path":721,"title":722,"description":723},"\u002Ftutorials\u002Fdatabase\u002Fmysql\u002Fmysql-lock","MySQL 锁","锁用于解决并发访问时的数据一致性问题。",{"path":725,"title":726,"description":727},"\u002Ftutorials\u002Fdatabase\u002Fmysql\u002Fmysql-optimize","MySQL 性能优化","SQL 优化是后端开发必备技能。",{"path":729,"title":730,"description":731},"\u002Ftutorials\u002Fdatabase\u002Fmysql\u002Fmysql-transaction","MySQL 事务","事务是一组不可分割的操作，要么全部成功，要么全部失败。",{"path":733,"title":734,"description":735},"\u002Ftutorials\u002Fdatabase\u002Fmysql\u002Fsql-advanced","SQL 进阶","多表查询、子查询、函数、视图、存储过程。",{"path":737,"title":738,"description":739},"\u002Ftutorials\u002Fdatabase\u002Fmysql\u002Fsql-basic","SQL 基础","SQL（Structured Query Language）是操作关系型数据库的标准语言。",{"path":741,"title":742,"description":743},"\u002Ftutorials\u002Fdatabase\u002Fredis\u002Fredis-advanced","Redis 进阶功能","事务、发布订阅、Lua 脚本、Pipeline。",{"path":745,"title":746,"description":747},"\u002Ftutorials\u002Fdatabase\u002Fredis\u002Fredis-basic","Redis 基础","Redis 安装配置与基本命令。",{"path":749,"title":750,"description":751},"\u002Ftutorials\u002Fdatabase\u002Fredis\u002Fredis-cluster","Redis 高可用","主从复制、哨兵、Cluster 集群。",{"path":753,"title":754,"description":755},"\u002Ftutorials\u002Fdatabase\u002Fredis\u002Fredis-datatype","Redis 数据类型","Redis 5 种基本数据类型 + 4 种特殊类型。",{"path":757,"title":758,"description":759},"\u002Ftutorials\u002Fdatabase\u002Fredis\u002Fredis-optimize","Redis 性能优化","内存优化、缓存问题、最佳实践。",{"path":761,"title":762,"description":763},"\u002Ftutorials\u002Fdatabase\u002Fredis\u002Fredis-persistence","Redis 持久化","Redis 提供 RDB 和 AOF 两种持久化方式。",{"path":765,"title":766,"description":767},"\u002Ftutorials\u002Fdatabase\u002Fredis\u002Fredis-principle","Redis 底层原理","数据结构、线程模型、网络模型。",{"path":769,"title":770,"description":771},"\u002Ftutorials\u002Fdev-idea\u002Fdesign-patterns\u002Fbehaiver-patterns\u002Fobserver-pattern","观察者模式","观察者模式属于行为型模式，定义了对象之间的一对多的依赖关系，在这种模式中，当一个对象的状态发生变化时，所有依赖于它的对象都会得到通知，并且执行相关操作。观察者模式又被成为“发布—订阅模式”，即发布者发生改变后，会通知所有订阅者。",{"path":773,"title":774,"description":11},"\u002Ftutorials\u002Fdev-idea\u002Fdesign-patterns\u002Fcreate-patterns\u002Ffactory-pattern","工厂模式",{"path":776,"title":777,"description":778},"\u002Ftutorials\u002Fdev-idea\u002Fdesign-patterns\u002Fcreate-patterns\u002Fsingleton-pattern","单例模式","单例模式是最常用的设计模式之一，他可以保证在整个应用中，某个类只存在一个实例化对象，即全局使用到该类的只有一个对象，这种模式在需要限制某些类的实例数量时非常有用，通常全局只需要一个该对象即可，如一些配置文件映射对象、数据库连接对象等。",{"path":780,"title":781,"description":782},"\u002Ftutorials\u002Fdev-idea\u002Fdesign-patterns\u002Fstructural-patterns\u002Fadapter-pattern","适配器模式","适配器模式是一种结构型模式，可以将一个类的接口转换成客户端所期望的另一种接口，适配器模式可以帮助开发人员在不修改现有代码的情况下，将不兼容的类组合在一起。",{"path":784,"title":785,"description":786},"\u002Ftutorials\u002Fdev-tools\u002Fgit\u002Fgit-basic-operations","Git 创建版本库","在 Git 上创建版本库有两种方式，一种是直接拷贝远程 Git 仓库到本地，另外一种是我们自己创建本地的版本库。",{"path":788,"title":789,"description":11},"\u002Ftutorials\u002Fdev-tools\u002Fgit\u002Fgit-branch-manage","Git 分支管理",{"path":791,"title":792,"description":11},"\u002Ftutorials\u002Fdev-tools\u002Fgit\u002Fgit-content-operations","Git 仓库内容操作",{"path":794,"title":795,"description":11},"\u002Ftutorials\u002Fdev-tools\u002Fgit\u002Fgit-introduce-install","Git 介绍和安装",{"path":797,"title":798,"description":11},"\u002Ftutorials\u002Fdev-tools\u002Fgit\u002Fgit-remote-manage","Git 远程管理",{"path":800,"title":801,"description":11},"\u002Ftutorials\u002Fdev-tools\u002Fgit\u002Fgit-workspace-index-repo","Git 工作原理",{"path":803,"title":804,"description":11},"\u002Ftutorials\u002Fdev-tools\u002Fhomebrew","HomeBrew 教程",{"path":806,"title":807,"description":11},"\u002Ftutorials\u002Fdev-tools\u002Fidea\u002Fshortcuts","快捷键",{"path":809,"title":810,"description":11},"\u002Ftutorials\u002Fdev-tools\u002Fmaven\u002Fintroduce-install-config","Maven - 介绍、安装、配置",{"path":812,"title":813,"description":11},"\u002Ftutorials\u002Ffront-end\u002Fvue3\u002Fbasic-knowledge","2. 基础知识",{"path":815,"title":816,"description":817},"\u002Ftutorials\u002Ffront-end\u002Fvue3\u002Fcomponent-communication","9. 组件通信","在前面的章节内，介绍了 Vue 中最核心的内容——组件的介绍和使用，和 Java 等编程语言相反，组件并不近似于这些变成语言中的类，类可以通过类或者其实例化的对象来相互交互，但 Vue 组件之间的作用域是相互独立的，这就意味着不同组件之间的数据无法相互引用。",{"path":819,"title":820,"description":821},"\u002Ftutorials\u002Ffront-end\u002Fvue3\u002Fcomputed","4. 计算属性","虽然直接在模板中使用表达式方便，但是如果在模板中添加很多逻辑，会让模板变的臃肿且难维护，耦合度较高。有没有一种简单的方式来实现呢？答案是有的。",{"path":823,"title":824,"description":11},"\u002Ftutorials\u002Ffront-end\u002Fvue3\u002Fcreate-vue-project","1. 环境搭建及安装",{"path":826,"title":827,"description":828},"\u002Ftutorials\u002Ffront-end\u002Fvue3\u002Flife-cycle","6. 生命周期","生命周期是指组件从创建、挂载、更新到销毁的整个过程中所经历的一系列阶段。在 Vue 中，每个组件都有自己的生命周期，可以通过生命周期钩子函数来监听和处理组件在不同阶段的行为和状态。",{"path":830,"title":831,"description":11},"\u002Ftutorials\u002Ffront-end\u002Fvue3\u002Fother-api","10. 其他 API",{"path":833,"title":834,"description":11},"\u002Ftutorials\u002Ffront-end\u002Fvue3\u002Fpinia","8. Pinia",{"path":836,"title":837,"description":11},"\u002Ftutorials\u002Ffront-end\u002Fvue3\u002Frouter","7. 路由",{"path":839,"title":840,"description":11},"\u002Ftutorials\u002Ffront-end\u002Fvue3\u002Ftemplate-grammar","3. 指令及模板语法",{"path":842,"title":843,"description":11},"\u002Ftutorials\u002Ffront-end\u002Fvue3\u002Fvue3-new-component","11. Vue3 新组件",{"path":845,"title":846,"description":847},"\u002Ftutorials\u002Ffront-end\u002Fvue3\u002Fwatch","5. 监视","Watch 是 Vue 提供的一个用于监视响应式数据变化并执行相应操作的 API，能够对响应式数据的变化做出一些操作的功能。Vue3 中的 Watch 支持多种用法，包括监视响应式对象、ref 对象、数组、函数等。",{"path":849,"title":850,"description":11},"\u002Ftutorials\u002Fmq\u002Fkafka\u002Fkafka-introduction","Kafka 简介与安装",{"path":852,"title":853,"description":11},"\u002Ftutorials\u002Fmq\u002Fkafka\u002Fkafka-producer-consumer","Kafka 生产者与消费者",{"path":855,"title":856,"description":857},"\u002Ftutorials\u002Fmq\u002Fkafka\u002Fkafka-springboot","Spring Boot 整合 Kafka","Spring Kafka 提供了对 Apache Kafka 的便捷集成。",{"path":859,"title":860,"description":861},"\u002Ftutorials\u002Fmq\u002Frabbitmq\u002Frabbitmq-exchange","RabbitMQ Exchange 详解","Exchange（交换机）是 RabbitMQ 的核心组件，负责接收生产者发送的消息，并根据规则将消息路由到一个或多个队列。",{"path":863,"title":864,"description":11},"\u002Ftutorials\u002Fmq\u002Frabbitmq\u002Frabbitmq-introduction","RabbitMQ 简介与安装",{"path":866,"title":867,"description":868},"\u002Ftutorials\u002Fmq\u002Frabbitmq\u002Frabbitmq-reliability","RabbitMQ 消息可靠性","消息可靠性是消息队列的核心要求，RabbitMQ 提供了多种机制来保证消息不丢失。",{"path":870,"title":871,"description":872},"\u002Ftutorials\u002Fmq\u002Frabbitmq\u002Frabbitmq-springboot","Spring Boot 整合 RabbitMQ","Spring AMQP 提供了对 RabbitMQ 的便捷集成，大大简化了开发工作。",{"path":874,"title":875,"description":11},"\u002Ftutorials\u002Fmq\u002Frocketmq\u002Frocketmq-client","RocketMQ 客户端使用",{"path":877,"title":878,"description":11},"\u002Ftutorials\u002Fmq\u002Frocketmq\u002Frocketmq-concepts","RocketMQ 核心概念",{"path":880,"title":881,"description":11},"\u002Ftutorials\u002Fmq\u002Frocketmq\u002Frocketmq-installation","RocketMQ 安装部署",{"path":883,"title":884,"description":885},"\u002Ftutorials\u002Fmq\u002Frocketmq\u002Frocketmq-message-type","RocketMQ 消息类型","RocketMQ 支持多种消息类型，满足不同业务场景需求。",{"id":887,"title":196,"body":888,"description":197,"extension":5969,"meta":5970,"navigation":980,"path":195,"seo":5971,"stem":5972,"__hash__":5973},"docs\u002Fgolang\u002Fdistributed\u002Fredis.md",{"type":889,"value":890,"toc":5940},"minimark",[891,894,898,923,927,931,1207,1210,1290,1293,1370,1373,1377,1878,1882,2333,2337,2752,2756,3109,3113,3649,3652,3656,3860,3863,4173,4177,4346,4349,4352,4680,4684,4875,4878,4882,5267,5271,5528,5532,5936],[892,893,197],"p",{},[895,896,897],"h2",{"id":897},"安装",[899,900,904],"pre",{"className":901,"code":902,"language":903,"meta":11,"style":11},"language-bash shiki shiki-themes github-light github-light github-dark","go get github.com\u002Fredis\u002Fgo-redis\u002Fv9\n","bash",[905,906,907],"code",{"__ignoreMap":11},[908,909,912,916,920],"span",{"class":910,"line":911},"line",1,[908,913,915],{"class":914},"snPdu","go",[908,917,919],{"class":918},"sIIMD"," get",[908,921,922],{"class":918}," github.com\u002Fredis\u002Fgo-redis\u002Fv9\n",[895,924,926],{"id":925},"连接-redis","连接 Redis",[928,929,930],"h3",{"id":930},"单机连接",[899,932,935],{"className":933,"code":934,"language":915,"meta":11,"style":11},"language-go shiki shiki-themes github-light github-light github-dark","import (\n    \"context\"\n    \"github.com\u002Fredis\u002Fgo-redis\u002Fv9\"\n)\n\nvar rdb *redis.Client\n\nfunc initRedis() {\n    rdb = redis.NewClient(&redis.Options{\n        Addr:     \"localhost:6379\",\n        Password: \"\",  \u002F\u002F 密码\n        DB:       0,   \u002F\u002F 数据库\n        PoolSize: 100, \u002F\u002F 连接池大小\n    })\n    \n    \u002F\u002F 测试连接\n    ctx := context.Background()\n    _, err := rdb.Ping(ctx).Result()\n    if err != nil {\n        panic(err)\n    }\n}\n",[905,936,937,947,959,969,975,982,1003,1008,1020,1051,1063,1079,1095,1110,1116,1122,1128,1146,1168,1186,1195,1201],{"__ignoreMap":11},[908,938,939,943],{"class":910,"line":911},[908,940,942],{"class":941},"s8jYJ","import",[908,944,946],{"class":945},"sxrX7"," (\n",[908,948,950,953,956],{"class":910,"line":949},2,[908,951,952],{"class":918},"    \"",[908,954,955],{"class":914},"context",[908,957,958],{"class":918},"\"\n",[908,960,962,964,967],{"class":910,"line":961},3,[908,963,952],{"class":918},[908,965,966],{"class":914},"github.com\u002Fredis\u002Fgo-redis\u002Fv9",[908,968,958],{"class":918},[908,970,972],{"class":910,"line":971},4,[908,973,974],{"class":945},")\n",[908,976,978],{"class":910,"line":977},5,[908,979,981],{"emptyLinePlaceholder":980},true,"\n",[908,983,985,988,991,994,997,1000],{"class":910,"line":984},6,[908,986,987],{"class":941},"var",[908,989,990],{"class":945}," rdb ",[908,992,993],{"class":941},"*",[908,995,996],{"class":914},"redis",[908,998,999],{"class":945},".",[908,1001,1002],{"class":914},"Client\n",[908,1004,1006],{"class":910,"line":1005},7,[908,1007,981],{"emptyLinePlaceholder":980},[908,1009,1011,1014,1017],{"class":910,"line":1010},8,[908,1012,1013],{"class":941},"func",[908,1015,1016],{"class":914}," initRedis",[908,1018,1019],{"class":945},"() {\n",[908,1021,1023,1026,1029,1032,1035,1038,1041,1043,1045,1048],{"class":910,"line":1022},9,[908,1024,1025],{"class":945},"    rdb ",[908,1027,1028],{"class":941},"=",[908,1030,1031],{"class":945}," redis.",[908,1033,1034],{"class":914},"NewClient",[908,1036,1037],{"class":945},"(",[908,1039,1040],{"class":941},"&",[908,1042,996],{"class":914},[908,1044,999],{"class":945},[908,1046,1047],{"class":914},"Options",[908,1049,1050],{"class":945},"{\n",[908,1052,1054,1057,1060],{"class":910,"line":1053},10,[908,1055,1056],{"class":945},"        Addr:     ",[908,1058,1059],{"class":918},"\"localhost:6379\"",[908,1061,1062],{"class":945},",\n",[908,1064,1066,1069,1072,1075],{"class":910,"line":1065},11,[908,1067,1068],{"class":945},"        Password: ",[908,1070,1071],{"class":918},"\"\"",[908,1073,1074],{"class":945},",  ",[908,1076,1078],{"class":1077},"sCsY4","\u002F\u002F 密码\n",[908,1080,1082,1085,1089,1092],{"class":910,"line":1081},12,[908,1083,1084],{"class":945},"        DB:       ",[908,1086,1088],{"class":1087},"sBjJW","0",[908,1090,1091],{"class":945},",   ",[908,1093,1094],{"class":1077},"\u002F\u002F 数据库\n",[908,1096,1098,1101,1104,1107],{"class":910,"line":1097},13,[908,1099,1100],{"class":945},"        PoolSize: ",[908,1102,1103],{"class":1087},"100",[908,1105,1106],{"class":945},", ",[908,1108,1109],{"class":1077},"\u002F\u002F 连接池大小\n",[908,1111,1113],{"class":910,"line":1112},14,[908,1114,1115],{"class":945},"    })\n",[908,1117,1119],{"class":910,"line":1118},15,[908,1120,1121],{"class":945},"    \n",[908,1123,1125],{"class":910,"line":1124},16,[908,1126,1127],{"class":1077},"    \u002F\u002F 测试连接\n",[908,1129,1131,1134,1137,1140,1143],{"class":910,"line":1130},17,[908,1132,1133],{"class":945},"    ctx ",[908,1135,1136],{"class":941},":=",[908,1138,1139],{"class":945}," context.",[908,1141,1142],{"class":914},"Background",[908,1144,1145],{"class":945},"()\n",[908,1147,1149,1152,1154,1157,1160,1163,1166],{"class":910,"line":1148},18,[908,1150,1151],{"class":945},"    _, err ",[908,1153,1136],{"class":941},[908,1155,1156],{"class":945}," rdb.",[908,1158,1159],{"class":914},"Ping",[908,1161,1162],{"class":945},"(ctx).",[908,1164,1165],{"class":914},"Result",[908,1167,1145],{"class":945},[908,1169,1171,1174,1177,1180,1183],{"class":910,"line":1170},19,[908,1172,1173],{"class":941},"    if",[908,1175,1176],{"class":945}," err ",[908,1178,1179],{"class":941},"!=",[908,1181,1182],{"class":1087}," nil",[908,1184,1185],{"class":945}," {\n",[908,1187,1189,1192],{"class":910,"line":1188},20,[908,1190,1191],{"class":914},"        panic",[908,1193,1194],{"class":945},"(err)\n",[908,1196,1198],{"class":910,"line":1197},21,[908,1199,1200],{"class":945},"    }\n",[908,1202,1204],{"class":910,"line":1203},22,[908,1205,1206],{"class":945},"}\n",[928,1208,1209],{"id":1209},"集群连接",[899,1211,1213],{"className":933,"code":1212,"language":915,"meta":11,"style":11},"rdb := redis.NewClusterClient(&redis.ClusterOptions{\n    Addrs: []string{\n        \"localhost:7000\",\n        \"localhost:7001\",\n        \"localhost:7002\",\n    },\n    Password: \"\",\n})\n",[905,1214,1215,1240,1250,1257,1264,1271,1276,1285],{"__ignoreMap":11},[908,1216,1217,1220,1222,1224,1227,1229,1231,1233,1235,1238],{"class":910,"line":911},[908,1218,1219],{"class":945},"rdb ",[908,1221,1136],{"class":941},[908,1223,1031],{"class":945},[908,1225,1226],{"class":914},"NewClusterClient",[908,1228,1037],{"class":945},[908,1230,1040],{"class":941},[908,1232,996],{"class":914},[908,1234,999],{"class":945},[908,1236,1237],{"class":914},"ClusterOptions",[908,1239,1050],{"class":945},[908,1241,1242,1245,1248],{"class":910,"line":949},[908,1243,1244],{"class":945},"    Addrs: []",[908,1246,1247],{"class":941},"string",[908,1249,1050],{"class":945},[908,1251,1252,1255],{"class":910,"line":961},[908,1253,1254],{"class":918},"        \"localhost:7000\"",[908,1256,1062],{"class":945},[908,1258,1259,1262],{"class":910,"line":971},[908,1260,1261],{"class":918},"        \"localhost:7001\"",[908,1263,1062],{"class":945},[908,1265,1266,1269],{"class":910,"line":977},[908,1267,1268],{"class":918},"        \"localhost:7002\"",[908,1270,1062],{"class":945},[908,1272,1273],{"class":910,"line":984},[908,1274,1275],{"class":945},"    },\n",[908,1277,1278,1281,1283],{"class":910,"line":1005},[908,1279,1280],{"class":945},"    Password: ",[908,1282,1071],{"class":918},[908,1284,1062],{"class":945},[908,1286,1287],{"class":910,"line":1010},[908,1288,1289],{"class":945},"})\n",[928,1291,1292],{"id":1292},"哨兵连接",[899,1294,1296],{"className":933,"code":1295,"language":915,"meta":11,"style":11},"rdb := redis.NewFailoverClient(&redis.FailoverOptions{\n    MasterName:    \"mymaster\",\n    SentinelAddrs: []string{\"localhost:26379\"},\n    Password:      \"\",\n    DB:            0,\n})\n",[905,1297,1298,1322,1332,1348,1357,1366],{"__ignoreMap":11},[908,1299,1300,1302,1304,1306,1309,1311,1313,1315,1317,1320],{"class":910,"line":911},[908,1301,1219],{"class":945},[908,1303,1136],{"class":941},[908,1305,1031],{"class":945},[908,1307,1308],{"class":914},"NewFailoverClient",[908,1310,1037],{"class":945},[908,1312,1040],{"class":941},[908,1314,996],{"class":914},[908,1316,999],{"class":945},[908,1318,1319],{"class":914},"FailoverOptions",[908,1321,1050],{"class":945},[908,1323,1324,1327,1330],{"class":910,"line":949},[908,1325,1326],{"class":945},"    MasterName:    ",[908,1328,1329],{"class":918},"\"mymaster\"",[908,1331,1062],{"class":945},[908,1333,1334,1337,1339,1342,1345],{"class":910,"line":961},[908,1335,1336],{"class":945},"    SentinelAddrs: []",[908,1338,1247],{"class":941},[908,1340,1341],{"class":945},"{",[908,1343,1344],{"class":918},"\"localhost:26379\"",[908,1346,1347],{"class":945},"},\n",[908,1349,1350,1353,1355],{"class":910,"line":971},[908,1351,1352],{"class":945},"    Password:      ",[908,1354,1071],{"class":918},[908,1356,1062],{"class":945},[908,1358,1359,1362,1364],{"class":910,"line":977},[908,1360,1361],{"class":945},"    DB:            ",[908,1363,1088],{"class":1087},[908,1365,1062],{"class":945},[908,1367,1368],{"class":910,"line":984},[908,1369,1289],{"class":945},[895,1371,1372],{"id":1372},"基本操作",[928,1374,1376],{"id":1375},"string-操作","String 操作",[899,1378,1380],{"className":933,"code":1379,"language":915,"meta":11,"style":11},"ctx := context.Background()\n\n\u002F\u002F 设置值\nerr := rdb.Set(ctx, \"key\", \"value\", 0).Err()  \u002F\u002F 0 表示不过期\nerr := rdb.Set(ctx, \"key\", \"value\", time.Hour).Err()  \u002F\u002F 1小时过期\n\n\u002F\u002F 设置值（不存在时）\nok, err := rdb.SetNX(ctx, \"key\", \"value\", time.Hour).Result()\n\n\u002F\u002F 设置值（存在时）\nok, err := rdb.SetXX(ctx, \"key\", \"value\", time.Hour).Result()\n\n\u002F\u002F 获取值\nval, err := rdb.Get(ctx, \"key\").Result()\nif err == redis.Nil {\n    fmt.Println(\"key 不存在\")\n}\n\n\u002F\u002F 批量设置\nerr := rdb.MSet(ctx, \"key1\", \"val1\", \"key2\", \"val2\").Err()\n\n\u002F\u002F 批量获取\nvals, err := rdb.MGet(ctx, \"key1\", \"key2\").Result()\n\n\u002F\u002F 自增\nn, err := rdb.Incr(ctx, \"counter\").Result()\nn, err := rdb.IncrBy(ctx, \"counter\", 10).Result()\n\n\u002F\u002F 自减\nn, err := rdb.Decr(ctx, \"counter\").Result()\nn, err := rdb.DecrBy(ctx, \"counter\", 10).Result()\n\n\u002F\u002F 追加\nlength, err := rdb.Append(ctx, \"key\", \"append\").Result()\n\n\u002F\u002F 获取长度\nlength, err := rdb.StrLen(ctx, \"key\").Result()\n",[905,1381,1382,1395,1399,1404,1443,1471,1475,1480,1506,1510,1515,1540,1544,1549,1571,1584,1599,1603,1607,1612,1649,1653,1658,1685,1690,1696,1720,1747,1752,1758,1780,1806,1811,1817,1845,1850,1856],{"__ignoreMap":11},[908,1383,1384,1387,1389,1391,1393],{"class":910,"line":911},[908,1385,1386],{"class":945},"ctx ",[908,1388,1136],{"class":941},[908,1390,1139],{"class":945},[908,1392,1142],{"class":914},[908,1394,1145],{"class":945},[908,1396,1397],{"class":910,"line":949},[908,1398,981],{"emptyLinePlaceholder":980},[908,1400,1401],{"class":910,"line":961},[908,1402,1403],{"class":1077},"\u002F\u002F 设置值\n",[908,1405,1406,1409,1411,1413,1416,1419,1422,1424,1427,1429,1431,1434,1437,1440],{"class":910,"line":971},[908,1407,1408],{"class":945},"err ",[908,1410,1136],{"class":941},[908,1412,1156],{"class":945},[908,1414,1415],{"class":914},"Set",[908,1417,1418],{"class":945},"(ctx, ",[908,1420,1421],{"class":918},"\"key\"",[908,1423,1106],{"class":945},[908,1425,1426],{"class":918},"\"value\"",[908,1428,1106],{"class":945},[908,1430,1088],{"class":1087},[908,1432,1433],{"class":945},").",[908,1435,1436],{"class":914},"Err",[908,1438,1439],{"class":945},"()  ",[908,1441,1442],{"class":1077},"\u002F\u002F 0 表示不过期\n",[908,1444,1445,1447,1449,1451,1453,1455,1457,1459,1461,1464,1466,1468],{"class":910,"line":977},[908,1446,1408],{"class":945},[908,1448,1136],{"class":941},[908,1450,1156],{"class":945},[908,1452,1415],{"class":914},[908,1454,1418],{"class":945},[908,1456,1421],{"class":918},[908,1458,1106],{"class":945},[908,1460,1426],{"class":918},[908,1462,1463],{"class":945},", time.Hour).",[908,1465,1436],{"class":914},[908,1467,1439],{"class":945},[908,1469,1470],{"class":1077},"\u002F\u002F 1小时过期\n",[908,1472,1473],{"class":910,"line":984},[908,1474,981],{"emptyLinePlaceholder":980},[908,1476,1477],{"class":910,"line":1005},[908,1478,1479],{"class":1077},"\u002F\u002F 设置值（不存在时）\n",[908,1481,1482,1485,1487,1489,1492,1494,1496,1498,1500,1502,1504],{"class":910,"line":1010},[908,1483,1484],{"class":945},"ok, err ",[908,1486,1136],{"class":941},[908,1488,1156],{"class":945},[908,1490,1491],{"class":914},"SetNX",[908,1493,1418],{"class":945},[908,1495,1421],{"class":918},[908,1497,1106],{"class":945},[908,1499,1426],{"class":918},[908,1501,1463],{"class":945},[908,1503,1165],{"class":914},[908,1505,1145],{"class":945},[908,1507,1508],{"class":910,"line":1022},[908,1509,981],{"emptyLinePlaceholder":980},[908,1511,1512],{"class":910,"line":1053},[908,1513,1514],{"class":1077},"\u002F\u002F 设置值（存在时）\n",[908,1516,1517,1519,1521,1523,1526,1528,1530,1532,1534,1536,1538],{"class":910,"line":1065},[908,1518,1484],{"class":945},[908,1520,1136],{"class":941},[908,1522,1156],{"class":945},[908,1524,1525],{"class":914},"SetXX",[908,1527,1418],{"class":945},[908,1529,1421],{"class":918},[908,1531,1106],{"class":945},[908,1533,1426],{"class":918},[908,1535,1463],{"class":945},[908,1537,1165],{"class":914},[908,1539,1145],{"class":945},[908,1541,1542],{"class":910,"line":1081},[908,1543,981],{"emptyLinePlaceholder":980},[908,1545,1546],{"class":910,"line":1097},[908,1547,1548],{"class":1077},"\u002F\u002F 获取值\n",[908,1550,1551,1554,1556,1558,1561,1563,1565,1567,1569],{"class":910,"line":1112},[908,1552,1553],{"class":945},"val, err ",[908,1555,1136],{"class":941},[908,1557,1156],{"class":945},[908,1559,1560],{"class":914},"Get",[908,1562,1418],{"class":945},[908,1564,1421],{"class":918},[908,1566,1433],{"class":945},[908,1568,1165],{"class":914},[908,1570,1145],{"class":945},[908,1572,1573,1576,1578,1581],{"class":910,"line":1118},[908,1574,1575],{"class":941},"if",[908,1577,1176],{"class":945},[908,1579,1580],{"class":941},"==",[908,1582,1583],{"class":945}," redis.Nil {\n",[908,1585,1586,1589,1592,1594,1597],{"class":910,"line":1124},[908,1587,1588],{"class":945},"    fmt.",[908,1590,1591],{"class":914},"Println",[908,1593,1037],{"class":945},[908,1595,1596],{"class":918},"\"key 不存在\"",[908,1598,974],{"class":945},[908,1600,1601],{"class":910,"line":1130},[908,1602,1206],{"class":945},[908,1604,1605],{"class":910,"line":1148},[908,1606,981],{"emptyLinePlaceholder":980},[908,1608,1609],{"class":910,"line":1170},[908,1610,1611],{"class":1077},"\u002F\u002F 批量设置\n",[908,1613,1614,1616,1618,1620,1623,1625,1628,1630,1633,1635,1638,1640,1643,1645,1647],{"class":910,"line":1188},[908,1615,1408],{"class":945},[908,1617,1136],{"class":941},[908,1619,1156],{"class":945},[908,1621,1622],{"class":914},"MSet",[908,1624,1418],{"class":945},[908,1626,1627],{"class":918},"\"key1\"",[908,1629,1106],{"class":945},[908,1631,1632],{"class":918},"\"val1\"",[908,1634,1106],{"class":945},[908,1636,1637],{"class":918},"\"key2\"",[908,1639,1106],{"class":945},[908,1641,1642],{"class":918},"\"val2\"",[908,1644,1433],{"class":945},[908,1646,1436],{"class":914},[908,1648,1145],{"class":945},[908,1650,1651],{"class":910,"line":1197},[908,1652,981],{"emptyLinePlaceholder":980},[908,1654,1655],{"class":910,"line":1203},[908,1656,1657],{"class":1077},"\u002F\u002F 批量获取\n",[908,1659,1661,1664,1666,1668,1671,1673,1675,1677,1679,1681,1683],{"class":910,"line":1660},23,[908,1662,1663],{"class":945},"vals, err ",[908,1665,1136],{"class":941},[908,1667,1156],{"class":945},[908,1669,1670],{"class":914},"MGet",[908,1672,1418],{"class":945},[908,1674,1627],{"class":918},[908,1676,1106],{"class":945},[908,1678,1637],{"class":918},[908,1680,1433],{"class":945},[908,1682,1165],{"class":914},[908,1684,1145],{"class":945},[908,1686,1688],{"class":910,"line":1687},24,[908,1689,981],{"emptyLinePlaceholder":980},[908,1691,1693],{"class":910,"line":1692},25,[908,1694,1695],{"class":1077},"\u002F\u002F 自增\n",[908,1697,1699,1702,1704,1706,1709,1711,1714,1716,1718],{"class":910,"line":1698},26,[908,1700,1701],{"class":945},"n, err ",[908,1703,1136],{"class":941},[908,1705,1156],{"class":945},[908,1707,1708],{"class":914},"Incr",[908,1710,1418],{"class":945},[908,1712,1713],{"class":918},"\"counter\"",[908,1715,1433],{"class":945},[908,1717,1165],{"class":914},[908,1719,1145],{"class":945},[908,1721,1723,1725,1727,1729,1732,1734,1736,1738,1741,1743,1745],{"class":910,"line":1722},27,[908,1724,1701],{"class":945},[908,1726,1136],{"class":941},[908,1728,1156],{"class":945},[908,1730,1731],{"class":914},"IncrBy",[908,1733,1418],{"class":945},[908,1735,1713],{"class":918},[908,1737,1106],{"class":945},[908,1739,1740],{"class":1087},"10",[908,1742,1433],{"class":945},[908,1744,1165],{"class":914},[908,1746,1145],{"class":945},[908,1748,1750],{"class":910,"line":1749},28,[908,1751,981],{"emptyLinePlaceholder":980},[908,1753,1755],{"class":910,"line":1754},29,[908,1756,1757],{"class":1077},"\u002F\u002F 自减\n",[908,1759,1761,1763,1765,1767,1770,1772,1774,1776,1778],{"class":910,"line":1760},30,[908,1762,1701],{"class":945},[908,1764,1136],{"class":941},[908,1766,1156],{"class":945},[908,1768,1769],{"class":914},"Decr",[908,1771,1418],{"class":945},[908,1773,1713],{"class":918},[908,1775,1433],{"class":945},[908,1777,1165],{"class":914},[908,1779,1145],{"class":945},[908,1781,1783,1785,1787,1789,1792,1794,1796,1798,1800,1802,1804],{"class":910,"line":1782},31,[908,1784,1701],{"class":945},[908,1786,1136],{"class":941},[908,1788,1156],{"class":945},[908,1790,1791],{"class":914},"DecrBy",[908,1793,1418],{"class":945},[908,1795,1713],{"class":918},[908,1797,1106],{"class":945},[908,1799,1740],{"class":1087},[908,1801,1433],{"class":945},[908,1803,1165],{"class":914},[908,1805,1145],{"class":945},[908,1807,1809],{"class":910,"line":1808},32,[908,1810,981],{"emptyLinePlaceholder":980},[908,1812,1814],{"class":910,"line":1813},33,[908,1815,1816],{"class":1077},"\u002F\u002F 追加\n",[908,1818,1820,1823,1825,1827,1830,1832,1834,1836,1839,1841,1843],{"class":910,"line":1819},34,[908,1821,1822],{"class":945},"length, err ",[908,1824,1136],{"class":941},[908,1826,1156],{"class":945},[908,1828,1829],{"class":914},"Append",[908,1831,1418],{"class":945},[908,1833,1421],{"class":918},[908,1835,1106],{"class":945},[908,1837,1838],{"class":918},"\"append\"",[908,1840,1433],{"class":945},[908,1842,1165],{"class":914},[908,1844,1145],{"class":945},[908,1846,1848],{"class":910,"line":1847},35,[908,1849,981],{"emptyLinePlaceholder":980},[908,1851,1853],{"class":910,"line":1852},36,[908,1854,1855],{"class":1077},"\u002F\u002F 获取长度\n",[908,1857,1859,1861,1863,1865,1868,1870,1872,1874,1876],{"class":910,"line":1858},37,[908,1860,1822],{"class":945},[908,1862,1136],{"class":941},[908,1864,1156],{"class":945},[908,1866,1867],{"class":914},"StrLen",[908,1869,1418],{"class":945},[908,1871,1421],{"class":918},[908,1873,1433],{"class":945},[908,1875,1165],{"class":914},[908,1877,1145],{"class":945},[928,1879,1881],{"id":1880},"hash-操作","Hash 操作",[899,1883,1885],{"className":933,"code":1884,"language":915,"meta":11,"style":11},"ctx := context.Background()\n\n\u002F\u002F 设置单个字段\nerr := rdb.HSet(ctx, \"user:1\", \"name\", \"张三\").Err()\n\n\u002F\u002F 设置多个字段\nerr := rdb.HSet(ctx, \"user:1\", map[string]interface{}{\n    \"name\":  \"张三\",\n    \"age\":   25,\n    \"email\": \"zhangsan@example.com\",\n}).Err()\n\n\u002F\u002F 获取单个字段\nval, err := rdb.HGet(ctx, \"user:1\", \"name\").Result()\n\n\u002F\u002F 获取多个字段\nvals, err := rdb.HMGet(ctx, \"user:1\", \"name\", \"age\").Result()\n\n\u002F\u002F 获取所有字段\nfields, err := rdb.HGetAll(ctx, \"user:1\").Result()\n\n\u002F\u002F 字段是否存在\nexists, err := rdb.HExists(ctx, \"user:1\", \"name\").Result()\n\n\u002F\u002F 删除字段\nn, err := rdb.HDel(ctx, \"user:1\", \"age\").Result()\n\n\u002F\u002F 字段自增\nn, err := rdb.HIncrBy(ctx, \"user:1\", \"age\", 1).Result()\n\n\u002F\u002F 获取所有字段名\nkeys, err := rdb.HKeys(ctx, \"user:1\").Result()\n\n\u002F\u002F 获取所有字段值\nvals, err := rdb.HVals(ctx, \"user:1\").Result()\n\n\u002F\u002F 获取字段数量\nlength, err := rdb.HLen(ctx, \"user:1\").Result()\n",[905,1886,1887,1899,1903,1908,1940,1944,1949,1982,1994,2007,2020,2029,2033,2038,2063,2067,2072,2102,2106,2111,2133,2137,2142,2168,2172,2177,2202,2206,2211,2241,2245,2250,2272,2276,2281,2302,2306,2311],{"__ignoreMap":11},[908,1888,1889,1891,1893,1895,1897],{"class":910,"line":911},[908,1890,1386],{"class":945},[908,1892,1136],{"class":941},[908,1894,1139],{"class":945},[908,1896,1142],{"class":914},[908,1898,1145],{"class":945},[908,1900,1901],{"class":910,"line":949},[908,1902,981],{"emptyLinePlaceholder":980},[908,1904,1905],{"class":910,"line":961},[908,1906,1907],{"class":1077},"\u002F\u002F 设置单个字段\n",[908,1909,1910,1912,1914,1916,1919,1921,1924,1926,1929,1931,1934,1936,1938],{"class":910,"line":971},[908,1911,1408],{"class":945},[908,1913,1136],{"class":941},[908,1915,1156],{"class":945},[908,1917,1918],{"class":914},"HSet",[908,1920,1418],{"class":945},[908,1922,1923],{"class":918},"\"user:1\"",[908,1925,1106],{"class":945},[908,1927,1928],{"class":918},"\"name\"",[908,1930,1106],{"class":945},[908,1932,1933],{"class":918},"\"张三\"",[908,1935,1433],{"class":945},[908,1937,1436],{"class":914},[908,1939,1145],{"class":945},[908,1941,1942],{"class":910,"line":977},[908,1943,981],{"emptyLinePlaceholder":980},[908,1945,1946],{"class":910,"line":984},[908,1947,1948],{"class":1077},"\u002F\u002F 设置多个字段\n",[908,1950,1951,1953,1955,1957,1959,1961,1963,1965,1968,1971,1973,1976,1979],{"class":910,"line":1005},[908,1952,1408],{"class":945},[908,1954,1136],{"class":941},[908,1956,1156],{"class":945},[908,1958,1918],{"class":914},[908,1960,1418],{"class":945},[908,1962,1923],{"class":918},[908,1964,1106],{"class":945},[908,1966,1967],{"class":941},"map",[908,1969,1970],{"class":945},"[",[908,1972,1247],{"class":941},[908,1974,1975],{"class":945},"]",[908,1977,1978],{"class":941},"interface",[908,1980,1981],{"class":945},"{}{\n",[908,1983,1984,1987,1990,1992],{"class":910,"line":1010},[908,1985,1986],{"class":918},"    \"name\"",[908,1988,1989],{"class":945},":  ",[908,1991,1933],{"class":918},[908,1993,1062],{"class":945},[908,1995,1996,1999,2002,2005],{"class":910,"line":1022},[908,1997,1998],{"class":918},"    \"age\"",[908,2000,2001],{"class":945},":   ",[908,2003,2004],{"class":1087},"25",[908,2006,1062],{"class":945},[908,2008,2009,2012,2015,2018],{"class":910,"line":1053},[908,2010,2011],{"class":918},"    \"email\"",[908,2013,2014],{"class":945},": ",[908,2016,2017],{"class":918},"\"zhangsan@example.com\"",[908,2019,1062],{"class":945},[908,2021,2022,2025,2027],{"class":910,"line":1065},[908,2023,2024],{"class":945},"}).",[908,2026,1436],{"class":914},[908,2028,1145],{"class":945},[908,2030,2031],{"class":910,"line":1081},[908,2032,981],{"emptyLinePlaceholder":980},[908,2034,2035],{"class":910,"line":1097},[908,2036,2037],{"class":1077},"\u002F\u002F 获取单个字段\n",[908,2039,2040,2042,2044,2046,2049,2051,2053,2055,2057,2059,2061],{"class":910,"line":1112},[908,2041,1553],{"class":945},[908,2043,1136],{"class":941},[908,2045,1156],{"class":945},[908,2047,2048],{"class":914},"HGet",[908,2050,1418],{"class":945},[908,2052,1923],{"class":918},[908,2054,1106],{"class":945},[908,2056,1928],{"class":918},[908,2058,1433],{"class":945},[908,2060,1165],{"class":914},[908,2062,1145],{"class":945},[908,2064,2065],{"class":910,"line":1118},[908,2066,981],{"emptyLinePlaceholder":980},[908,2068,2069],{"class":910,"line":1124},[908,2070,2071],{"class":1077},"\u002F\u002F 获取多个字段\n",[908,2073,2074,2076,2078,2080,2083,2085,2087,2089,2091,2093,2096,2098,2100],{"class":910,"line":1130},[908,2075,1663],{"class":945},[908,2077,1136],{"class":941},[908,2079,1156],{"class":945},[908,2081,2082],{"class":914},"HMGet",[908,2084,1418],{"class":945},[908,2086,1923],{"class":918},[908,2088,1106],{"class":945},[908,2090,1928],{"class":918},[908,2092,1106],{"class":945},[908,2094,2095],{"class":918},"\"age\"",[908,2097,1433],{"class":945},[908,2099,1165],{"class":914},[908,2101,1145],{"class":945},[908,2103,2104],{"class":910,"line":1148},[908,2105,981],{"emptyLinePlaceholder":980},[908,2107,2108],{"class":910,"line":1170},[908,2109,2110],{"class":1077},"\u002F\u002F 获取所有字段\n",[908,2112,2113,2116,2118,2120,2123,2125,2127,2129,2131],{"class":910,"line":1188},[908,2114,2115],{"class":945},"fields, err ",[908,2117,1136],{"class":941},[908,2119,1156],{"class":945},[908,2121,2122],{"class":914},"HGetAll",[908,2124,1418],{"class":945},[908,2126,1923],{"class":918},[908,2128,1433],{"class":945},[908,2130,1165],{"class":914},[908,2132,1145],{"class":945},[908,2134,2135],{"class":910,"line":1197},[908,2136,981],{"emptyLinePlaceholder":980},[908,2138,2139],{"class":910,"line":1203},[908,2140,2141],{"class":1077},"\u002F\u002F 字段是否存在\n",[908,2143,2144,2147,2149,2151,2154,2156,2158,2160,2162,2164,2166],{"class":910,"line":1660},[908,2145,2146],{"class":945},"exists, err ",[908,2148,1136],{"class":941},[908,2150,1156],{"class":945},[908,2152,2153],{"class":914},"HExists",[908,2155,1418],{"class":945},[908,2157,1923],{"class":918},[908,2159,1106],{"class":945},[908,2161,1928],{"class":918},[908,2163,1433],{"class":945},[908,2165,1165],{"class":914},[908,2167,1145],{"class":945},[908,2169,2170],{"class":910,"line":1687},[908,2171,981],{"emptyLinePlaceholder":980},[908,2173,2174],{"class":910,"line":1692},[908,2175,2176],{"class":1077},"\u002F\u002F 删除字段\n",[908,2178,2179,2181,2183,2185,2188,2190,2192,2194,2196,2198,2200],{"class":910,"line":1698},[908,2180,1701],{"class":945},[908,2182,1136],{"class":941},[908,2184,1156],{"class":945},[908,2186,2187],{"class":914},"HDel",[908,2189,1418],{"class":945},[908,2191,1923],{"class":918},[908,2193,1106],{"class":945},[908,2195,2095],{"class":918},[908,2197,1433],{"class":945},[908,2199,1165],{"class":914},[908,2201,1145],{"class":945},[908,2203,2204],{"class":910,"line":1722},[908,2205,981],{"emptyLinePlaceholder":980},[908,2207,2208],{"class":910,"line":1749},[908,2209,2210],{"class":1077},"\u002F\u002F 字段自增\n",[908,2212,2213,2215,2217,2219,2222,2224,2226,2228,2230,2232,2235,2237,2239],{"class":910,"line":1754},[908,2214,1701],{"class":945},[908,2216,1136],{"class":941},[908,2218,1156],{"class":945},[908,2220,2221],{"class":914},"HIncrBy",[908,2223,1418],{"class":945},[908,2225,1923],{"class":918},[908,2227,1106],{"class":945},[908,2229,2095],{"class":918},[908,2231,1106],{"class":945},[908,2233,2234],{"class":1087},"1",[908,2236,1433],{"class":945},[908,2238,1165],{"class":914},[908,2240,1145],{"class":945},[908,2242,2243],{"class":910,"line":1760},[908,2244,981],{"emptyLinePlaceholder":980},[908,2246,2247],{"class":910,"line":1782},[908,2248,2249],{"class":1077},"\u002F\u002F 获取所有字段名\n",[908,2251,2252,2255,2257,2259,2262,2264,2266,2268,2270],{"class":910,"line":1808},[908,2253,2254],{"class":945},"keys, err ",[908,2256,1136],{"class":941},[908,2258,1156],{"class":945},[908,2260,2261],{"class":914},"HKeys",[908,2263,1418],{"class":945},[908,2265,1923],{"class":918},[908,2267,1433],{"class":945},[908,2269,1165],{"class":914},[908,2271,1145],{"class":945},[908,2273,2274],{"class":910,"line":1813},[908,2275,981],{"emptyLinePlaceholder":980},[908,2277,2278],{"class":910,"line":1819},[908,2279,2280],{"class":1077},"\u002F\u002F 获取所有字段值\n",[908,2282,2283,2285,2287,2289,2292,2294,2296,2298,2300],{"class":910,"line":1847},[908,2284,1663],{"class":945},[908,2286,1136],{"class":941},[908,2288,1156],{"class":945},[908,2290,2291],{"class":914},"HVals",[908,2293,1418],{"class":945},[908,2295,1923],{"class":918},[908,2297,1433],{"class":945},[908,2299,1165],{"class":914},[908,2301,1145],{"class":945},[908,2303,2304],{"class":910,"line":1852},[908,2305,981],{"emptyLinePlaceholder":980},[908,2307,2308],{"class":910,"line":1858},[908,2309,2310],{"class":1077},"\u002F\u002F 获取字段数量\n",[908,2312,2314,2316,2318,2320,2323,2325,2327,2329,2331],{"class":910,"line":2313},38,[908,2315,1822],{"class":945},[908,2317,1136],{"class":941},[908,2319,1156],{"class":945},[908,2321,2322],{"class":914},"HLen",[908,2324,1418],{"class":945},[908,2326,1923],{"class":918},[908,2328,1433],{"class":945},[908,2330,1165],{"class":914},[908,2332,1145],{"class":945},[928,2334,2336],{"id":2335},"list-操作","List 操作",[899,2338,2340],{"className":933,"code":2339,"language":915,"meta":11,"style":11},"ctx := context.Background()\n\n\u002F\u002F 左侧插入\nn, err := rdb.LPush(ctx, \"list\", \"a\", \"b\", \"c\").Result()\n\n\u002F\u002F 右侧插入\nn, err := rdb.RPush(ctx, \"list\", \"d\", \"e\").Result()\n\n\u002F\u002F 左侧弹出\nval, err := rdb.LPop(ctx, \"list\").Result()\n\n\u002F\u002F 右侧弹出\nval, err := rdb.RPop(ctx, \"list\").Result()\n\n\u002F\u002F 获取范围\nvals, err := rdb.LRange(ctx, \"list\", 0, -1).Result()  \u002F\u002F 获取全部\n\n\u002F\u002F 获取长度\nlength, err := rdb.LLen(ctx, \"list\").Result()\n\n\u002F\u002F 获取索引位置的值\nval, err := rdb.LIndex(ctx, \"list\", 0).Result()\n\n\u002F\u002F 设置索引位置的值\nerr := rdb.LSet(ctx, \"list\", 0, \"new\").Err()\n\n\u002F\u002F 删除元素\nn, err := rdb.LRem(ctx, \"list\", 1, \"a\").Result()  \u002F\u002F 删除1个值为\"a\"的元素\n\n\u002F\u002F 阻塞弹出\nval, err := rdb.BLPop(ctx, time.Second*5, \"list\").Result()\nval, err := rdb.BRPop(ctx, time.Second*5, \"list\").Result()\n",[905,2341,2342,2354,2358,2363,2400,2404,2409,2440,2444,2449,2470,2474,2479,2500,2504,2509,2544,2548,2552,2573,2577,2582,2607,2611,2616,2646,2650,2655,2687,2691,2696,2725],{"__ignoreMap":11},[908,2343,2344,2346,2348,2350,2352],{"class":910,"line":911},[908,2345,1386],{"class":945},[908,2347,1136],{"class":941},[908,2349,1139],{"class":945},[908,2351,1142],{"class":914},[908,2353,1145],{"class":945},[908,2355,2356],{"class":910,"line":949},[908,2357,981],{"emptyLinePlaceholder":980},[908,2359,2360],{"class":910,"line":961},[908,2361,2362],{"class":1077},"\u002F\u002F 左侧插入\n",[908,2364,2365,2367,2369,2371,2374,2376,2379,2381,2384,2386,2389,2391,2394,2396,2398],{"class":910,"line":971},[908,2366,1701],{"class":945},[908,2368,1136],{"class":941},[908,2370,1156],{"class":945},[908,2372,2373],{"class":914},"LPush",[908,2375,1418],{"class":945},[908,2377,2378],{"class":918},"\"list\"",[908,2380,1106],{"class":945},[908,2382,2383],{"class":918},"\"a\"",[908,2385,1106],{"class":945},[908,2387,2388],{"class":918},"\"b\"",[908,2390,1106],{"class":945},[908,2392,2393],{"class":918},"\"c\"",[908,2395,1433],{"class":945},[908,2397,1165],{"class":914},[908,2399,1145],{"class":945},[908,2401,2402],{"class":910,"line":977},[908,2403,981],{"emptyLinePlaceholder":980},[908,2405,2406],{"class":910,"line":984},[908,2407,2408],{"class":1077},"\u002F\u002F 右侧插入\n",[908,2410,2411,2413,2415,2417,2420,2422,2424,2426,2429,2431,2434,2436,2438],{"class":910,"line":1005},[908,2412,1701],{"class":945},[908,2414,1136],{"class":941},[908,2416,1156],{"class":945},[908,2418,2419],{"class":914},"RPush",[908,2421,1418],{"class":945},[908,2423,2378],{"class":918},[908,2425,1106],{"class":945},[908,2427,2428],{"class":918},"\"d\"",[908,2430,1106],{"class":945},[908,2432,2433],{"class":918},"\"e\"",[908,2435,1433],{"class":945},[908,2437,1165],{"class":914},[908,2439,1145],{"class":945},[908,2441,2442],{"class":910,"line":1010},[908,2443,981],{"emptyLinePlaceholder":980},[908,2445,2446],{"class":910,"line":1022},[908,2447,2448],{"class":1077},"\u002F\u002F 左侧弹出\n",[908,2450,2451,2453,2455,2457,2460,2462,2464,2466,2468],{"class":910,"line":1053},[908,2452,1553],{"class":945},[908,2454,1136],{"class":941},[908,2456,1156],{"class":945},[908,2458,2459],{"class":914},"LPop",[908,2461,1418],{"class":945},[908,2463,2378],{"class":918},[908,2465,1433],{"class":945},[908,2467,1165],{"class":914},[908,2469,1145],{"class":945},[908,2471,2472],{"class":910,"line":1065},[908,2473,981],{"emptyLinePlaceholder":980},[908,2475,2476],{"class":910,"line":1081},[908,2477,2478],{"class":1077},"\u002F\u002F 右侧弹出\n",[908,2480,2481,2483,2485,2487,2490,2492,2494,2496,2498],{"class":910,"line":1097},[908,2482,1553],{"class":945},[908,2484,1136],{"class":941},[908,2486,1156],{"class":945},[908,2488,2489],{"class":914},"RPop",[908,2491,1418],{"class":945},[908,2493,2378],{"class":918},[908,2495,1433],{"class":945},[908,2497,1165],{"class":914},[908,2499,1145],{"class":945},[908,2501,2502],{"class":910,"line":1112},[908,2503,981],{"emptyLinePlaceholder":980},[908,2505,2506],{"class":910,"line":1118},[908,2507,2508],{"class":1077},"\u002F\u002F 获取范围\n",[908,2510,2511,2513,2515,2517,2520,2522,2524,2526,2528,2530,2533,2535,2537,2539,2541],{"class":910,"line":1124},[908,2512,1663],{"class":945},[908,2514,1136],{"class":941},[908,2516,1156],{"class":945},[908,2518,2519],{"class":914},"LRange",[908,2521,1418],{"class":945},[908,2523,2378],{"class":918},[908,2525,1106],{"class":945},[908,2527,1088],{"class":1087},[908,2529,1106],{"class":945},[908,2531,2532],{"class":941},"-",[908,2534,2234],{"class":1087},[908,2536,1433],{"class":945},[908,2538,1165],{"class":914},[908,2540,1439],{"class":945},[908,2542,2543],{"class":1077},"\u002F\u002F 获取全部\n",[908,2545,2546],{"class":910,"line":1130},[908,2547,981],{"emptyLinePlaceholder":980},[908,2549,2550],{"class":910,"line":1148},[908,2551,1855],{"class":1077},[908,2553,2554,2556,2558,2560,2563,2565,2567,2569,2571],{"class":910,"line":1170},[908,2555,1822],{"class":945},[908,2557,1136],{"class":941},[908,2559,1156],{"class":945},[908,2561,2562],{"class":914},"LLen",[908,2564,1418],{"class":945},[908,2566,2378],{"class":918},[908,2568,1433],{"class":945},[908,2570,1165],{"class":914},[908,2572,1145],{"class":945},[908,2574,2575],{"class":910,"line":1188},[908,2576,981],{"emptyLinePlaceholder":980},[908,2578,2579],{"class":910,"line":1197},[908,2580,2581],{"class":1077},"\u002F\u002F 获取索引位置的值\n",[908,2583,2584,2586,2588,2590,2593,2595,2597,2599,2601,2603,2605],{"class":910,"line":1203},[908,2585,1553],{"class":945},[908,2587,1136],{"class":941},[908,2589,1156],{"class":945},[908,2591,2592],{"class":914},"LIndex",[908,2594,1418],{"class":945},[908,2596,2378],{"class":918},[908,2598,1106],{"class":945},[908,2600,1088],{"class":1087},[908,2602,1433],{"class":945},[908,2604,1165],{"class":914},[908,2606,1145],{"class":945},[908,2608,2609],{"class":910,"line":1660},[908,2610,981],{"emptyLinePlaceholder":980},[908,2612,2613],{"class":910,"line":1687},[908,2614,2615],{"class":1077},"\u002F\u002F 设置索引位置的值\n",[908,2617,2618,2620,2622,2624,2627,2629,2631,2633,2635,2637,2640,2642,2644],{"class":910,"line":1692},[908,2619,1408],{"class":945},[908,2621,1136],{"class":941},[908,2623,1156],{"class":945},[908,2625,2626],{"class":914},"LSet",[908,2628,1418],{"class":945},[908,2630,2378],{"class":918},[908,2632,1106],{"class":945},[908,2634,1088],{"class":1087},[908,2636,1106],{"class":945},[908,2638,2639],{"class":918},"\"new\"",[908,2641,1433],{"class":945},[908,2643,1436],{"class":914},[908,2645,1145],{"class":945},[908,2647,2648],{"class":910,"line":1698},[908,2649,981],{"emptyLinePlaceholder":980},[908,2651,2652],{"class":910,"line":1722},[908,2653,2654],{"class":1077},"\u002F\u002F 删除元素\n",[908,2656,2657,2659,2661,2663,2666,2668,2670,2672,2674,2676,2678,2680,2682,2684],{"class":910,"line":1749},[908,2658,1701],{"class":945},[908,2660,1136],{"class":941},[908,2662,1156],{"class":945},[908,2664,2665],{"class":914},"LRem",[908,2667,1418],{"class":945},[908,2669,2378],{"class":918},[908,2671,1106],{"class":945},[908,2673,2234],{"class":1087},[908,2675,1106],{"class":945},[908,2677,2383],{"class":918},[908,2679,1433],{"class":945},[908,2681,1165],{"class":914},[908,2683,1439],{"class":945},[908,2685,2686],{"class":1077},"\u002F\u002F 删除1个值为\"a\"的元素\n",[908,2688,2689],{"class":910,"line":1754},[908,2690,981],{"emptyLinePlaceholder":980},[908,2692,2693],{"class":910,"line":1760},[908,2694,2695],{"class":1077},"\u002F\u002F 阻塞弹出\n",[908,2697,2698,2700,2702,2704,2707,2710,2712,2715,2717,2719,2721,2723],{"class":910,"line":1782},[908,2699,1553],{"class":945},[908,2701,1136],{"class":941},[908,2703,1156],{"class":945},[908,2705,2706],{"class":914},"BLPop",[908,2708,2709],{"class":945},"(ctx, time.Second",[908,2711,993],{"class":941},[908,2713,2714],{"class":1087},"5",[908,2716,1106],{"class":945},[908,2718,2378],{"class":918},[908,2720,1433],{"class":945},[908,2722,1165],{"class":914},[908,2724,1145],{"class":945},[908,2726,2727,2729,2731,2733,2736,2738,2740,2742,2744,2746,2748,2750],{"class":910,"line":1808},[908,2728,1553],{"class":945},[908,2730,1136],{"class":941},[908,2732,1156],{"class":945},[908,2734,2735],{"class":914},"BRPop",[908,2737,2709],{"class":945},[908,2739,993],{"class":941},[908,2741,2714],{"class":1087},[908,2743,1106],{"class":945},[908,2745,2378],{"class":918},[908,2747,1433],{"class":945},[908,2749,1165],{"class":914},[908,2751,1145],{"class":945},[928,2753,2755],{"id":2754},"set-操作","Set 操作",[899,2757,2759],{"className":933,"code":2758,"language":915,"meta":11,"style":11},"ctx := context.Background()\n\n\u002F\u002F 添加成员\nn, err := rdb.SAdd(ctx, \"set\", \"a\", \"b\", \"c\").Result()\n\n\u002F\u002F 获取所有成员\nmembers, err := rdb.SMembers(ctx, \"set\").Result()\n\n\u002F\u002F 判断是否是成员\nisMember, err := rdb.SIsMember(ctx, \"set\", \"a\").Result()\n\n\u002F\u002F 获取成员数量\ncount, err := rdb.SCard(ctx, \"set\").Result()\n\n\u002F\u002F 删除成员\nn, err := rdb.SRem(ctx, \"set\", \"a\").Result()\n\n\u002F\u002F 随机获取成员\nmember, err := rdb.SRandMember(ctx, \"set\").Result()\n\n\u002F\u002F 随机弹出成员\nmember, err := rdb.SPop(ctx, \"set\").Result()\n\n\u002F\u002F 集合运算\n\u002F\u002F 交集\nvals, err := rdb.SInter(ctx, \"set1\", \"set2\").Result()\n\u002F\u002F 并集\nvals, err := rdb.SUnion(ctx, \"set1\", \"set2\").Result()\n\u002F\u002F 差集\nvals, err := rdb.SDiff(ctx, \"set1\", \"set2\").Result()\n",[905,2760,2761,2773,2777,2782,2816,2820,2825,2847,2851,2856,2882,2886,2891,2913,2917,2922,2947,2951,2956,2978,2982,2987,3008,3012,3017,3022,3049,3054,3079,3084],{"__ignoreMap":11},[908,2762,2763,2765,2767,2769,2771],{"class":910,"line":911},[908,2764,1386],{"class":945},[908,2766,1136],{"class":941},[908,2768,1139],{"class":945},[908,2770,1142],{"class":914},[908,2772,1145],{"class":945},[908,2774,2775],{"class":910,"line":949},[908,2776,981],{"emptyLinePlaceholder":980},[908,2778,2779],{"class":910,"line":961},[908,2780,2781],{"class":1077},"\u002F\u002F 添加成员\n",[908,2783,2784,2786,2788,2790,2793,2795,2798,2800,2802,2804,2806,2808,2810,2812,2814],{"class":910,"line":971},[908,2785,1701],{"class":945},[908,2787,1136],{"class":941},[908,2789,1156],{"class":945},[908,2791,2792],{"class":914},"SAdd",[908,2794,1418],{"class":945},[908,2796,2797],{"class":918},"\"set\"",[908,2799,1106],{"class":945},[908,2801,2383],{"class":918},[908,2803,1106],{"class":945},[908,2805,2388],{"class":918},[908,2807,1106],{"class":945},[908,2809,2393],{"class":918},[908,2811,1433],{"class":945},[908,2813,1165],{"class":914},[908,2815,1145],{"class":945},[908,2817,2818],{"class":910,"line":977},[908,2819,981],{"emptyLinePlaceholder":980},[908,2821,2822],{"class":910,"line":984},[908,2823,2824],{"class":1077},"\u002F\u002F 获取所有成员\n",[908,2826,2827,2830,2832,2834,2837,2839,2841,2843,2845],{"class":910,"line":1005},[908,2828,2829],{"class":945},"members, err ",[908,2831,1136],{"class":941},[908,2833,1156],{"class":945},[908,2835,2836],{"class":914},"SMembers",[908,2838,1418],{"class":945},[908,2840,2797],{"class":918},[908,2842,1433],{"class":945},[908,2844,1165],{"class":914},[908,2846,1145],{"class":945},[908,2848,2849],{"class":910,"line":1010},[908,2850,981],{"emptyLinePlaceholder":980},[908,2852,2853],{"class":910,"line":1022},[908,2854,2855],{"class":1077},"\u002F\u002F 判断是否是成员\n",[908,2857,2858,2861,2863,2865,2868,2870,2872,2874,2876,2878,2880],{"class":910,"line":1053},[908,2859,2860],{"class":945},"isMember, err ",[908,2862,1136],{"class":941},[908,2864,1156],{"class":945},[908,2866,2867],{"class":914},"SIsMember",[908,2869,1418],{"class":945},[908,2871,2797],{"class":918},[908,2873,1106],{"class":945},[908,2875,2383],{"class":918},[908,2877,1433],{"class":945},[908,2879,1165],{"class":914},[908,2881,1145],{"class":945},[908,2883,2884],{"class":910,"line":1065},[908,2885,981],{"emptyLinePlaceholder":980},[908,2887,2888],{"class":910,"line":1081},[908,2889,2890],{"class":1077},"\u002F\u002F 获取成员数量\n",[908,2892,2893,2896,2898,2900,2903,2905,2907,2909,2911],{"class":910,"line":1097},[908,2894,2895],{"class":945},"count, err ",[908,2897,1136],{"class":941},[908,2899,1156],{"class":945},[908,2901,2902],{"class":914},"SCard",[908,2904,1418],{"class":945},[908,2906,2797],{"class":918},[908,2908,1433],{"class":945},[908,2910,1165],{"class":914},[908,2912,1145],{"class":945},[908,2914,2915],{"class":910,"line":1112},[908,2916,981],{"emptyLinePlaceholder":980},[908,2918,2919],{"class":910,"line":1118},[908,2920,2921],{"class":1077},"\u002F\u002F 删除成员\n",[908,2923,2924,2926,2928,2930,2933,2935,2937,2939,2941,2943,2945],{"class":910,"line":1124},[908,2925,1701],{"class":945},[908,2927,1136],{"class":941},[908,2929,1156],{"class":945},[908,2931,2932],{"class":914},"SRem",[908,2934,1418],{"class":945},[908,2936,2797],{"class":918},[908,2938,1106],{"class":945},[908,2940,2383],{"class":918},[908,2942,1433],{"class":945},[908,2944,1165],{"class":914},[908,2946,1145],{"class":945},[908,2948,2949],{"class":910,"line":1130},[908,2950,981],{"emptyLinePlaceholder":980},[908,2952,2953],{"class":910,"line":1148},[908,2954,2955],{"class":1077},"\u002F\u002F 随机获取成员\n",[908,2957,2958,2961,2963,2965,2968,2970,2972,2974,2976],{"class":910,"line":1170},[908,2959,2960],{"class":945},"member, err ",[908,2962,1136],{"class":941},[908,2964,1156],{"class":945},[908,2966,2967],{"class":914},"SRandMember",[908,2969,1418],{"class":945},[908,2971,2797],{"class":918},[908,2973,1433],{"class":945},[908,2975,1165],{"class":914},[908,2977,1145],{"class":945},[908,2979,2980],{"class":910,"line":1188},[908,2981,981],{"emptyLinePlaceholder":980},[908,2983,2984],{"class":910,"line":1197},[908,2985,2986],{"class":1077},"\u002F\u002F 随机弹出成员\n",[908,2988,2989,2991,2993,2995,2998,3000,3002,3004,3006],{"class":910,"line":1203},[908,2990,2960],{"class":945},[908,2992,1136],{"class":941},[908,2994,1156],{"class":945},[908,2996,2997],{"class":914},"SPop",[908,2999,1418],{"class":945},[908,3001,2797],{"class":918},[908,3003,1433],{"class":945},[908,3005,1165],{"class":914},[908,3007,1145],{"class":945},[908,3009,3010],{"class":910,"line":1660},[908,3011,981],{"emptyLinePlaceholder":980},[908,3013,3014],{"class":910,"line":1687},[908,3015,3016],{"class":1077},"\u002F\u002F 集合运算\n",[908,3018,3019],{"class":910,"line":1692},[908,3020,3021],{"class":1077},"\u002F\u002F 交集\n",[908,3023,3024,3026,3028,3030,3033,3035,3038,3040,3043,3045,3047],{"class":910,"line":1698},[908,3025,1663],{"class":945},[908,3027,1136],{"class":941},[908,3029,1156],{"class":945},[908,3031,3032],{"class":914},"SInter",[908,3034,1418],{"class":945},[908,3036,3037],{"class":918},"\"set1\"",[908,3039,1106],{"class":945},[908,3041,3042],{"class":918},"\"set2\"",[908,3044,1433],{"class":945},[908,3046,1165],{"class":914},[908,3048,1145],{"class":945},[908,3050,3051],{"class":910,"line":1722},[908,3052,3053],{"class":1077},"\u002F\u002F 并集\n",[908,3055,3056,3058,3060,3062,3065,3067,3069,3071,3073,3075,3077],{"class":910,"line":1749},[908,3057,1663],{"class":945},[908,3059,1136],{"class":941},[908,3061,1156],{"class":945},[908,3063,3064],{"class":914},"SUnion",[908,3066,1418],{"class":945},[908,3068,3037],{"class":918},[908,3070,1106],{"class":945},[908,3072,3042],{"class":918},[908,3074,1433],{"class":945},[908,3076,1165],{"class":914},[908,3078,1145],{"class":945},[908,3080,3081],{"class":910,"line":1754},[908,3082,3083],{"class":1077},"\u002F\u002F 差集\n",[908,3085,3086,3088,3090,3092,3095,3097,3099,3101,3103,3105,3107],{"class":910,"line":1760},[908,3087,1663],{"class":945},[908,3089,1136],{"class":941},[908,3091,1156],{"class":945},[908,3093,3094],{"class":914},"SDiff",[908,3096,1418],{"class":945},[908,3098,3037],{"class":918},[908,3100,1106],{"class":945},[908,3102,3042],{"class":918},[908,3104,1433],{"class":945},[908,3106,1165],{"class":914},[908,3108,1145],{"class":945},[928,3110,3112],{"id":3111},"sorted-set-操作","Sorted Set 操作",[899,3114,3116],{"className":933,"code":3115,"language":915,"meta":11,"style":11},"ctx := context.Background()\n\n\u002F\u002F 添加成员\nn, err := rdb.ZAdd(ctx, \"zset\", redis.Z{Score: 100, Member: \"张三\"}).Result()\n\n\u002F\u002F 批量添加\nn, err := rdb.ZAdd(ctx, \"zset\",\n    redis.Z{Score: 90, Member: \"李四\"},\n    redis.Z{Score: 80, Member: \"王五\"},\n).Result()\n\n\u002F\u002F 获取分数\nscore, err := rdb.ZScore(ctx, \"zset\", \"张三\").Result()\n\n\u002F\u002F 分数自增\nnewScore, err := rdb.ZIncrBy(ctx, \"zset\", 10, \"张三\").Result()\n\n\u002F\u002F 获取排名（从小到大）\nrank, err := rdb.ZRank(ctx, \"zset\", \"张三\").Result()\n\n\u002F\u002F 获取排名（从大到小）\nrank, err := rdb.ZRevRank(ctx, \"zset\", \"张三\").Result()\n\n\u002F\u002F 按排名获取（从小到大）\nvals, err := rdb.ZRange(ctx, \"zset\", 0, -1).Result()\n\n\u002F\u002F 按排名获取（从大到小）\nvals, err := rdb.ZRevRange(ctx, \"zset\", 0, 9).Result()  \u002F\u002F Top 10\n\n\u002F\u002F 按分数范围获取\nvals, err := rdb.ZRangeByScore(ctx, \"zset\", &redis.ZRangeBy{\n    Min: \"80\",\n    Max: \"100\",\n}).Result()\n\n\u002F\u002F 获取成员数量\ncount, err := rdb.ZCard(ctx, \"zset\").Result()\n\n\u002F\u002F 删除成员\nn, err := rdb.ZRem(ctx, \"zset\", \"张三\").Result()\n\n\u002F\u002F 按排名删除\nn, err := rdb.ZRemRangeByRank(ctx, \"zset\", 0, 2).Result()\n",[905,3117,3118,3130,3134,3138,3179,3183,3188,3204,3225,3245,3253,3257,3262,3288,3292,3297,3327,3331,3336,3362,3366,3371,3396,3400,3405,3436,3440,3445,3478,3482,3487,3515,3525,3535,3543,3547,3551,3572,3576,3581,3607,3612,3618],{"__ignoreMap":11},[908,3119,3120,3122,3124,3126,3128],{"class":910,"line":911},[908,3121,1386],{"class":945},[908,3123,1136],{"class":941},[908,3125,1139],{"class":945},[908,3127,1142],{"class":914},[908,3129,1145],{"class":945},[908,3131,3132],{"class":910,"line":949},[908,3133,981],{"emptyLinePlaceholder":980},[908,3135,3136],{"class":910,"line":961},[908,3137,2781],{"class":1077},[908,3139,3140,3142,3144,3146,3149,3151,3154,3156,3158,3160,3163,3166,3168,3171,3173,3175,3177],{"class":910,"line":971},[908,3141,1701],{"class":945},[908,3143,1136],{"class":941},[908,3145,1156],{"class":945},[908,3147,3148],{"class":914},"ZAdd",[908,3150,1418],{"class":945},[908,3152,3153],{"class":918},"\"zset\"",[908,3155,1106],{"class":945},[908,3157,996],{"class":914},[908,3159,999],{"class":945},[908,3161,3162],{"class":914},"Z",[908,3164,3165],{"class":945},"{Score: ",[908,3167,1103],{"class":1087},[908,3169,3170],{"class":945},", Member: ",[908,3172,1933],{"class":918},[908,3174,2024],{"class":945},[908,3176,1165],{"class":914},[908,3178,1145],{"class":945},[908,3180,3181],{"class":910,"line":977},[908,3182,981],{"emptyLinePlaceholder":980},[908,3184,3185],{"class":910,"line":984},[908,3186,3187],{"class":1077},"\u002F\u002F 批量添加\n",[908,3189,3190,3192,3194,3196,3198,3200,3202],{"class":910,"line":1005},[908,3191,1701],{"class":945},[908,3193,1136],{"class":941},[908,3195,1156],{"class":945},[908,3197,3148],{"class":914},[908,3199,1418],{"class":945},[908,3201,3153],{"class":918},[908,3203,1062],{"class":945},[908,3205,3206,3209,3211,3213,3215,3218,3220,3223],{"class":910,"line":1010},[908,3207,3208],{"class":914},"    redis",[908,3210,999],{"class":945},[908,3212,3162],{"class":914},[908,3214,3165],{"class":945},[908,3216,3217],{"class":1087},"90",[908,3219,3170],{"class":945},[908,3221,3222],{"class":918},"\"李四\"",[908,3224,1347],{"class":945},[908,3226,3227,3229,3231,3233,3235,3238,3240,3243],{"class":910,"line":1022},[908,3228,3208],{"class":914},[908,3230,999],{"class":945},[908,3232,3162],{"class":914},[908,3234,3165],{"class":945},[908,3236,3237],{"class":1087},"80",[908,3239,3170],{"class":945},[908,3241,3242],{"class":918},"\"王五\"",[908,3244,1347],{"class":945},[908,3246,3247,3249,3251],{"class":910,"line":1053},[908,3248,1433],{"class":945},[908,3250,1165],{"class":914},[908,3252,1145],{"class":945},[908,3254,3255],{"class":910,"line":1065},[908,3256,981],{"emptyLinePlaceholder":980},[908,3258,3259],{"class":910,"line":1081},[908,3260,3261],{"class":1077},"\u002F\u002F 获取分数\n",[908,3263,3264,3267,3269,3271,3274,3276,3278,3280,3282,3284,3286],{"class":910,"line":1097},[908,3265,3266],{"class":945},"score, err ",[908,3268,1136],{"class":941},[908,3270,1156],{"class":945},[908,3272,3273],{"class":914},"ZScore",[908,3275,1418],{"class":945},[908,3277,3153],{"class":918},[908,3279,1106],{"class":945},[908,3281,1933],{"class":918},[908,3283,1433],{"class":945},[908,3285,1165],{"class":914},[908,3287,1145],{"class":945},[908,3289,3290],{"class":910,"line":1112},[908,3291,981],{"emptyLinePlaceholder":980},[908,3293,3294],{"class":910,"line":1118},[908,3295,3296],{"class":1077},"\u002F\u002F 分数自增\n",[908,3298,3299,3302,3304,3306,3309,3311,3313,3315,3317,3319,3321,3323,3325],{"class":910,"line":1124},[908,3300,3301],{"class":945},"newScore, err ",[908,3303,1136],{"class":941},[908,3305,1156],{"class":945},[908,3307,3308],{"class":914},"ZIncrBy",[908,3310,1418],{"class":945},[908,3312,3153],{"class":918},[908,3314,1106],{"class":945},[908,3316,1740],{"class":1087},[908,3318,1106],{"class":945},[908,3320,1933],{"class":918},[908,3322,1433],{"class":945},[908,3324,1165],{"class":914},[908,3326,1145],{"class":945},[908,3328,3329],{"class":910,"line":1130},[908,3330,981],{"emptyLinePlaceholder":980},[908,3332,3333],{"class":910,"line":1148},[908,3334,3335],{"class":1077},"\u002F\u002F 获取排名（从小到大）\n",[908,3337,3338,3341,3343,3345,3348,3350,3352,3354,3356,3358,3360],{"class":910,"line":1170},[908,3339,3340],{"class":945},"rank, err ",[908,3342,1136],{"class":941},[908,3344,1156],{"class":945},[908,3346,3347],{"class":914},"ZRank",[908,3349,1418],{"class":945},[908,3351,3153],{"class":918},[908,3353,1106],{"class":945},[908,3355,1933],{"class":918},[908,3357,1433],{"class":945},[908,3359,1165],{"class":914},[908,3361,1145],{"class":945},[908,3363,3364],{"class":910,"line":1188},[908,3365,981],{"emptyLinePlaceholder":980},[908,3367,3368],{"class":910,"line":1197},[908,3369,3370],{"class":1077},"\u002F\u002F 获取排名（从大到小）\n",[908,3372,3373,3375,3377,3379,3382,3384,3386,3388,3390,3392,3394],{"class":910,"line":1203},[908,3374,3340],{"class":945},[908,3376,1136],{"class":941},[908,3378,1156],{"class":945},[908,3380,3381],{"class":914},"ZRevRank",[908,3383,1418],{"class":945},[908,3385,3153],{"class":918},[908,3387,1106],{"class":945},[908,3389,1933],{"class":918},[908,3391,1433],{"class":945},[908,3393,1165],{"class":914},[908,3395,1145],{"class":945},[908,3397,3398],{"class":910,"line":1660},[908,3399,981],{"emptyLinePlaceholder":980},[908,3401,3402],{"class":910,"line":1687},[908,3403,3404],{"class":1077},"\u002F\u002F 按排名获取（从小到大）\n",[908,3406,3407,3409,3411,3413,3416,3418,3420,3422,3424,3426,3428,3430,3432,3434],{"class":910,"line":1692},[908,3408,1663],{"class":945},[908,3410,1136],{"class":941},[908,3412,1156],{"class":945},[908,3414,3415],{"class":914},"ZRange",[908,3417,1418],{"class":945},[908,3419,3153],{"class":918},[908,3421,1106],{"class":945},[908,3423,1088],{"class":1087},[908,3425,1106],{"class":945},[908,3427,2532],{"class":941},[908,3429,2234],{"class":1087},[908,3431,1433],{"class":945},[908,3433,1165],{"class":914},[908,3435,1145],{"class":945},[908,3437,3438],{"class":910,"line":1698},[908,3439,981],{"emptyLinePlaceholder":980},[908,3441,3442],{"class":910,"line":1722},[908,3443,3444],{"class":1077},"\u002F\u002F 按排名获取（从大到小）\n",[908,3446,3447,3449,3451,3453,3456,3458,3460,3462,3464,3466,3469,3471,3473,3475],{"class":910,"line":1749},[908,3448,1663],{"class":945},[908,3450,1136],{"class":941},[908,3452,1156],{"class":945},[908,3454,3455],{"class":914},"ZRevRange",[908,3457,1418],{"class":945},[908,3459,3153],{"class":918},[908,3461,1106],{"class":945},[908,3463,1088],{"class":1087},[908,3465,1106],{"class":945},[908,3467,3468],{"class":1087},"9",[908,3470,1433],{"class":945},[908,3472,1165],{"class":914},[908,3474,1439],{"class":945},[908,3476,3477],{"class":1077},"\u002F\u002F Top 10\n",[908,3479,3480],{"class":910,"line":1754},[908,3481,981],{"emptyLinePlaceholder":980},[908,3483,3484],{"class":910,"line":1760},[908,3485,3486],{"class":1077},"\u002F\u002F 按分数范围获取\n",[908,3488,3489,3491,3493,3495,3498,3500,3502,3504,3506,3508,3510,3513],{"class":910,"line":1782},[908,3490,1663],{"class":945},[908,3492,1136],{"class":941},[908,3494,1156],{"class":945},[908,3496,3497],{"class":914},"ZRangeByScore",[908,3499,1418],{"class":945},[908,3501,3153],{"class":918},[908,3503,1106],{"class":945},[908,3505,1040],{"class":941},[908,3507,996],{"class":914},[908,3509,999],{"class":945},[908,3511,3512],{"class":914},"ZRangeBy",[908,3514,1050],{"class":945},[908,3516,3517,3520,3523],{"class":910,"line":1808},[908,3518,3519],{"class":945},"    Min: ",[908,3521,3522],{"class":918},"\"80\"",[908,3524,1062],{"class":945},[908,3526,3527,3530,3533],{"class":910,"line":1813},[908,3528,3529],{"class":945},"    Max: ",[908,3531,3532],{"class":918},"\"100\"",[908,3534,1062],{"class":945},[908,3536,3537,3539,3541],{"class":910,"line":1819},[908,3538,2024],{"class":945},[908,3540,1165],{"class":914},[908,3542,1145],{"class":945},[908,3544,3545],{"class":910,"line":1847},[908,3546,981],{"emptyLinePlaceholder":980},[908,3548,3549],{"class":910,"line":1852},[908,3550,2890],{"class":1077},[908,3552,3553,3555,3557,3559,3562,3564,3566,3568,3570],{"class":910,"line":1858},[908,3554,2895],{"class":945},[908,3556,1136],{"class":941},[908,3558,1156],{"class":945},[908,3560,3561],{"class":914},"ZCard",[908,3563,1418],{"class":945},[908,3565,3153],{"class":918},[908,3567,1433],{"class":945},[908,3569,1165],{"class":914},[908,3571,1145],{"class":945},[908,3573,3574],{"class":910,"line":2313},[908,3575,981],{"emptyLinePlaceholder":980},[908,3577,3579],{"class":910,"line":3578},39,[908,3580,2921],{"class":1077},[908,3582,3584,3586,3588,3590,3593,3595,3597,3599,3601,3603,3605],{"class":910,"line":3583},40,[908,3585,1701],{"class":945},[908,3587,1136],{"class":941},[908,3589,1156],{"class":945},[908,3591,3592],{"class":914},"ZRem",[908,3594,1418],{"class":945},[908,3596,3153],{"class":918},[908,3598,1106],{"class":945},[908,3600,1933],{"class":918},[908,3602,1433],{"class":945},[908,3604,1165],{"class":914},[908,3606,1145],{"class":945},[908,3608,3610],{"class":910,"line":3609},41,[908,3611,981],{"emptyLinePlaceholder":980},[908,3613,3615],{"class":910,"line":3614},42,[908,3616,3617],{"class":1077},"\u002F\u002F 按排名删除\n",[908,3619,3621,3623,3625,3627,3630,3632,3634,3636,3638,3640,3643,3645,3647],{"class":910,"line":3620},43,[908,3622,1701],{"class":945},[908,3624,1136],{"class":941},[908,3626,1156],{"class":945},[908,3628,3629],{"class":914},"ZRemRangeByRank",[908,3631,1418],{"class":945},[908,3633,3153],{"class":918},[908,3635,1106],{"class":945},[908,3637,1088],{"class":1087},[908,3639,1106],{"class":945},[908,3641,3642],{"class":1087},"2",[908,3644,1433],{"class":945},[908,3646,1165],{"class":914},[908,3648,1145],{"class":945},[895,3650,3651],{"id":3651},"高级操作",[928,3653,3655],{"id":3654},"管道pipeline","管道（Pipeline）",[899,3657,3659],{"className":933,"code":3658,"language":915,"meta":11,"style":11},"ctx := context.Background()\n\n\u002F\u002F 管道：批量发送命令，减少网络往返\npipe := rdb.Pipeline()\n\npipe.Set(ctx, \"key1\", \"value1\", 0)\npipe.Set(ctx, \"key2\", \"value2\", 0)\npipe.Get(ctx, \"key1\")\npipe.Get(ctx, \"key2\")\n\ncmds, err := pipe.Exec(ctx)\nif err != nil {\n    panic(err)\n}\n\nfor _, cmd := range cmds {\n    fmt.Println(cmd.(*redis.StringCmd).Val())\n}\n",[905,3660,3661,3673,3677,3682,3696,3700,3722,3743,3755,3767,3771,3787,3799,3806,3810,3814,3830,3856],{"__ignoreMap":11},[908,3662,3663,3665,3667,3669,3671],{"class":910,"line":911},[908,3664,1386],{"class":945},[908,3666,1136],{"class":941},[908,3668,1139],{"class":945},[908,3670,1142],{"class":914},[908,3672,1145],{"class":945},[908,3674,3675],{"class":910,"line":949},[908,3676,981],{"emptyLinePlaceholder":980},[908,3678,3679],{"class":910,"line":961},[908,3680,3681],{"class":1077},"\u002F\u002F 管道：批量发送命令，减少网络往返\n",[908,3683,3684,3687,3689,3691,3694],{"class":910,"line":971},[908,3685,3686],{"class":945},"pipe ",[908,3688,1136],{"class":941},[908,3690,1156],{"class":945},[908,3692,3693],{"class":914},"Pipeline",[908,3695,1145],{"class":945},[908,3697,3698],{"class":910,"line":977},[908,3699,981],{"emptyLinePlaceholder":980},[908,3701,3702,3705,3707,3709,3711,3713,3716,3718,3720],{"class":910,"line":984},[908,3703,3704],{"class":945},"pipe.",[908,3706,1415],{"class":914},[908,3708,1418],{"class":945},[908,3710,1627],{"class":918},[908,3712,1106],{"class":945},[908,3714,3715],{"class":918},"\"value1\"",[908,3717,1106],{"class":945},[908,3719,1088],{"class":1087},[908,3721,974],{"class":945},[908,3723,3724,3726,3728,3730,3732,3734,3737,3739,3741],{"class":910,"line":1005},[908,3725,3704],{"class":945},[908,3727,1415],{"class":914},[908,3729,1418],{"class":945},[908,3731,1637],{"class":918},[908,3733,1106],{"class":945},[908,3735,3736],{"class":918},"\"value2\"",[908,3738,1106],{"class":945},[908,3740,1088],{"class":1087},[908,3742,974],{"class":945},[908,3744,3745,3747,3749,3751,3753],{"class":910,"line":1010},[908,3746,3704],{"class":945},[908,3748,1560],{"class":914},[908,3750,1418],{"class":945},[908,3752,1627],{"class":918},[908,3754,974],{"class":945},[908,3756,3757,3759,3761,3763,3765],{"class":910,"line":1022},[908,3758,3704],{"class":945},[908,3760,1560],{"class":914},[908,3762,1418],{"class":945},[908,3764,1637],{"class":918},[908,3766,974],{"class":945},[908,3768,3769],{"class":910,"line":1053},[908,3770,981],{"emptyLinePlaceholder":980},[908,3772,3773,3776,3778,3781,3784],{"class":910,"line":1065},[908,3774,3775],{"class":945},"cmds, err ",[908,3777,1136],{"class":941},[908,3779,3780],{"class":945}," pipe.",[908,3782,3783],{"class":914},"Exec",[908,3785,3786],{"class":945},"(ctx)\n",[908,3788,3789,3791,3793,3795,3797],{"class":910,"line":1081},[908,3790,1575],{"class":941},[908,3792,1176],{"class":945},[908,3794,1179],{"class":941},[908,3796,1182],{"class":1087},[908,3798,1185],{"class":945},[908,3800,3801,3804],{"class":910,"line":1097},[908,3802,3803],{"class":914},"    panic",[908,3805,1194],{"class":945},[908,3807,3808],{"class":910,"line":1112},[908,3809,1206],{"class":945},[908,3811,3812],{"class":910,"line":1118},[908,3813,981],{"emptyLinePlaceholder":980},[908,3815,3816,3819,3822,3824,3827],{"class":910,"line":1124},[908,3817,3818],{"class":941},"for",[908,3820,3821],{"class":945}," _, cmd ",[908,3823,1136],{"class":941},[908,3825,3826],{"class":941}," range",[908,3828,3829],{"class":945}," cmds {\n",[908,3831,3832,3834,3836,3839,3841,3843,3845,3848,3850,3853],{"class":910,"line":1130},[908,3833,1588],{"class":945},[908,3835,1591],{"class":914},[908,3837,3838],{"class":945},"(cmd.(",[908,3840,993],{"class":941},[908,3842,996],{"class":914},[908,3844,999],{"class":945},[908,3846,3847],{"class":914},"StringCmd",[908,3849,1433],{"class":945},[908,3851,3852],{"class":914},"Val",[908,3854,3855],{"class":945},"())\n",[908,3857,3858],{"class":910,"line":1148},[908,3859,1206],{"class":945},[928,3861,3862],{"id":3862},"事务",[899,3864,3866],{"className":933,"code":3865,"language":915,"meta":11,"style":11},"ctx := context.Background()\n\n\u002F\u002F 事务：原子性执行多个命令\n_, err := rdb.TxPipelined(ctx, func(pipe redis.Pipeliner) error {\n    pipe.Set(ctx, \"key1\", \"value1\", 0)\n    pipe.Set(ctx, \"key2\", \"value2\", 0)\n    return nil\n})\n\n\u002F\u002F Watch：乐观锁\nerr := rdb.Watch(ctx, func(tx *redis.Tx) error {\n    \u002F\u002F 获取当前值\n    n, err := tx.Get(ctx, \"counter\").Int()\n    if err != nil && err != redis.Nil {\n        return err\n    }\n    \n    \u002F\u002F 在事务中修改\n    _, err = tx.TxPipelined(ctx, func(pipe redis.Pipeliner) error {\n        pipe.Set(ctx, \"counter\", n+1, 0)\n        return nil\n    })\n    return err\n}, \"counter\")\n",[905,3867,3868,3880,3884,3889,3927,3948,3968,3976,3980,3984,3989,4025,4030,4053,4072,4080,4084,4088,4093,4123,4148,4154,4158,4164],{"__ignoreMap":11},[908,3869,3870,3872,3874,3876,3878],{"class":910,"line":911},[908,3871,1386],{"class":945},[908,3873,1136],{"class":941},[908,3875,1139],{"class":945},[908,3877,1142],{"class":914},[908,3879,1145],{"class":945},[908,3881,3882],{"class":910,"line":949},[908,3883,981],{"emptyLinePlaceholder":980},[908,3885,3886],{"class":910,"line":961},[908,3887,3888],{"class":1077},"\u002F\u002F 事务：原子性执行多个命令\n",[908,3890,3891,3894,3896,3898,3901,3903,3905,3907,3911,3914,3916,3919,3922,3925],{"class":910,"line":971},[908,3892,3893],{"class":945},"_, err ",[908,3895,1136],{"class":941},[908,3897,1156],{"class":945},[908,3899,3900],{"class":914},"TxPipelined",[908,3902,1418],{"class":945},[908,3904,1013],{"class":941},[908,3906,1037],{"class":945},[908,3908,3910],{"class":3909},"sP4rz","pipe",[908,3912,3913],{"class":914}," redis",[908,3915,999],{"class":945},[908,3917,3918],{"class":914},"Pipeliner",[908,3920,3921],{"class":945},") ",[908,3923,3924],{"class":941},"error",[908,3926,1185],{"class":945},[908,3928,3929,3932,3934,3936,3938,3940,3942,3944,3946],{"class":910,"line":977},[908,3930,3931],{"class":945},"    pipe.",[908,3933,1415],{"class":914},[908,3935,1418],{"class":945},[908,3937,1627],{"class":918},[908,3939,1106],{"class":945},[908,3941,3715],{"class":918},[908,3943,1106],{"class":945},[908,3945,1088],{"class":1087},[908,3947,974],{"class":945},[908,3949,3950,3952,3954,3956,3958,3960,3962,3964,3966],{"class":910,"line":984},[908,3951,3931],{"class":945},[908,3953,1415],{"class":914},[908,3955,1418],{"class":945},[908,3957,1637],{"class":918},[908,3959,1106],{"class":945},[908,3961,3736],{"class":918},[908,3963,1106],{"class":945},[908,3965,1088],{"class":1087},[908,3967,974],{"class":945},[908,3969,3970,3973],{"class":910,"line":1005},[908,3971,3972],{"class":941},"    return",[908,3974,3975],{"class":1087}," nil\n",[908,3977,3978],{"class":910,"line":1010},[908,3979,1289],{"class":945},[908,3981,3982],{"class":910,"line":1022},[908,3983,981],{"emptyLinePlaceholder":980},[908,3985,3986],{"class":910,"line":1053},[908,3987,3988],{"class":1077},"\u002F\u002F Watch：乐观锁\n",[908,3990,3991,3993,3995,3997,4000,4002,4004,4006,4009,4012,4014,4016,4019,4021,4023],{"class":910,"line":1065},[908,3992,1408],{"class":945},[908,3994,1136],{"class":941},[908,3996,1156],{"class":945},[908,3998,3999],{"class":914},"Watch",[908,4001,1418],{"class":945},[908,4003,1013],{"class":941},[908,4005,1037],{"class":945},[908,4007,4008],{"class":3909},"tx",[908,4010,4011],{"class":941}," *",[908,4013,996],{"class":914},[908,4015,999],{"class":945},[908,4017,4018],{"class":914},"Tx",[908,4020,3921],{"class":945},[908,4022,3924],{"class":941},[908,4024,1185],{"class":945},[908,4026,4027],{"class":910,"line":1081},[908,4028,4029],{"class":1077},"    \u002F\u002F 获取当前值\n",[908,4031,4032,4035,4037,4040,4042,4044,4046,4048,4051],{"class":910,"line":1097},[908,4033,4034],{"class":945},"    n, err ",[908,4036,1136],{"class":941},[908,4038,4039],{"class":945}," tx.",[908,4041,1560],{"class":914},[908,4043,1418],{"class":945},[908,4045,1713],{"class":918},[908,4047,1433],{"class":945},[908,4049,4050],{"class":914},"Int",[908,4052,1145],{"class":945},[908,4054,4055,4057,4059,4061,4063,4066,4068,4070],{"class":910,"line":1112},[908,4056,1173],{"class":941},[908,4058,1176],{"class":945},[908,4060,1179],{"class":941},[908,4062,1182],{"class":1087},[908,4064,4065],{"class":941}," &&",[908,4067,1176],{"class":945},[908,4069,1179],{"class":941},[908,4071,1583],{"class":945},[908,4073,4074,4077],{"class":910,"line":1118},[908,4075,4076],{"class":941},"        return",[908,4078,4079],{"class":945}," err\n",[908,4081,4082],{"class":910,"line":1124},[908,4083,1200],{"class":945},[908,4085,4086],{"class":910,"line":1130},[908,4087,1121],{"class":945},[908,4089,4090],{"class":910,"line":1148},[908,4091,4092],{"class":1077},"    \u002F\u002F 在事务中修改\n",[908,4094,4095,4097,4099,4101,4103,4105,4107,4109,4111,4113,4115,4117,4119,4121],{"class":910,"line":1170},[908,4096,1151],{"class":945},[908,4098,1028],{"class":941},[908,4100,4039],{"class":945},[908,4102,3900],{"class":914},[908,4104,1418],{"class":945},[908,4106,1013],{"class":941},[908,4108,1037],{"class":945},[908,4110,3910],{"class":3909},[908,4112,3913],{"class":914},[908,4114,999],{"class":945},[908,4116,3918],{"class":914},[908,4118,3921],{"class":945},[908,4120,3924],{"class":941},[908,4122,1185],{"class":945},[908,4124,4125,4128,4130,4132,4134,4137,4140,4142,4144,4146],{"class":910,"line":1188},[908,4126,4127],{"class":945},"        pipe.",[908,4129,1415],{"class":914},[908,4131,1418],{"class":945},[908,4133,1713],{"class":918},[908,4135,4136],{"class":945},", n",[908,4138,4139],{"class":941},"+",[908,4141,2234],{"class":1087},[908,4143,1106],{"class":945},[908,4145,1088],{"class":1087},[908,4147,974],{"class":945},[908,4149,4150,4152],{"class":910,"line":1197},[908,4151,4076],{"class":941},[908,4153,3975],{"class":1087},[908,4155,4156],{"class":910,"line":1203},[908,4157,1115],{"class":945},[908,4159,4160,4162],{"class":910,"line":1660},[908,4161,3972],{"class":941},[908,4163,4079],{"class":945},[908,4165,4166,4169,4171],{"class":910,"line":1687},[908,4167,4168],{"class":945},"}, ",[908,4170,1713],{"class":918},[908,4172,974],{"class":945},[928,4174,4176],{"id":4175},"lua-脚本","Lua 脚本",[899,4178,4180],{"className":933,"code":4179,"language":915,"meta":11,"style":11},"ctx := context.Background()\n\n\u002F\u002F 简单脚本\nscript := redis.NewScript(`\n    return redis.call('set', KEYS[1], ARGV[1])\n`)\nerr := script.Run(ctx, rdb, []string{\"key\"}, \"value\").Err()\n\n\u002F\u002F 复杂脚本（原子操作）\nscript := redis.NewScript(`\n    local current = redis.call('get', KEYS[1])\n    if current == false then\n        return redis.call('set', KEYS[1], ARGV[1])\n    end\n    return nil\n`)\nresult, err := script.Run(ctx, rdb, []string{\"key\"}, \"value\").Result()\n",[905,4181,4182,4194,4198,4203,4220,4225,4232,4263,4267,4272,4286,4291,4296,4301,4306,4311,4317],{"__ignoreMap":11},[908,4183,4184,4186,4188,4190,4192],{"class":910,"line":911},[908,4185,1386],{"class":945},[908,4187,1136],{"class":941},[908,4189,1139],{"class":945},[908,4191,1142],{"class":914},[908,4193,1145],{"class":945},[908,4195,4196],{"class":910,"line":949},[908,4197,981],{"emptyLinePlaceholder":980},[908,4199,4200],{"class":910,"line":961},[908,4201,4202],{"class":1077},"\u002F\u002F 简单脚本\n",[908,4204,4205,4208,4210,4212,4215,4217],{"class":910,"line":971},[908,4206,4207],{"class":945},"script ",[908,4209,1136],{"class":941},[908,4211,1031],{"class":945},[908,4213,4214],{"class":914},"NewScript",[908,4216,1037],{"class":945},[908,4218,4219],{"class":918},"`\n",[908,4221,4222],{"class":910,"line":977},[908,4223,4224],{"class":918},"    return redis.call('set', KEYS[1], ARGV[1])\n",[908,4226,4227,4230],{"class":910,"line":984},[908,4228,4229],{"class":918},"`",[908,4231,974],{"class":945},[908,4233,4234,4236,4238,4241,4244,4247,4249,4251,4253,4255,4257,4259,4261],{"class":910,"line":1005},[908,4235,1408],{"class":945},[908,4237,1136],{"class":941},[908,4239,4240],{"class":945}," script.",[908,4242,4243],{"class":914},"Run",[908,4245,4246],{"class":945},"(ctx, rdb, []",[908,4248,1247],{"class":941},[908,4250,1341],{"class":945},[908,4252,1421],{"class":918},[908,4254,4168],{"class":945},[908,4256,1426],{"class":918},[908,4258,1433],{"class":945},[908,4260,1436],{"class":914},[908,4262,1145],{"class":945},[908,4264,4265],{"class":910,"line":1010},[908,4266,981],{"emptyLinePlaceholder":980},[908,4268,4269],{"class":910,"line":1022},[908,4270,4271],{"class":1077},"\u002F\u002F 复杂脚本（原子操作）\n",[908,4273,4274,4276,4278,4280,4282,4284],{"class":910,"line":1053},[908,4275,4207],{"class":945},[908,4277,1136],{"class":941},[908,4279,1031],{"class":945},[908,4281,4214],{"class":914},[908,4283,1037],{"class":945},[908,4285,4219],{"class":918},[908,4287,4288],{"class":910,"line":1065},[908,4289,4290],{"class":918},"    local current = redis.call('get', KEYS[1])\n",[908,4292,4293],{"class":910,"line":1081},[908,4294,4295],{"class":918},"    if current == false then\n",[908,4297,4298],{"class":910,"line":1097},[908,4299,4300],{"class":918},"        return redis.call('set', KEYS[1], ARGV[1])\n",[908,4302,4303],{"class":910,"line":1112},[908,4304,4305],{"class":918},"    end\n",[908,4307,4308],{"class":910,"line":1118},[908,4309,4310],{"class":918},"    return nil\n",[908,4312,4313,4315],{"class":910,"line":1124},[908,4314,4229],{"class":918},[908,4316,974],{"class":945},[908,4318,4319,4322,4324,4326,4328,4330,4332,4334,4336,4338,4340,4342,4344],{"class":910,"line":1130},[908,4320,4321],{"class":945},"result, err ",[908,4323,1136],{"class":941},[908,4325,4240],{"class":945},[908,4327,4243],{"class":914},[908,4329,4246],{"class":945},[908,4331,1247],{"class":941},[908,4333,1341],{"class":945},[908,4335,1421],{"class":918},[908,4337,4168],{"class":945},[908,4339,1426],{"class":918},[908,4341,1433],{"class":945},[908,4343,1165],{"class":914},[908,4345,1145],{"class":945},[895,4347,4348],{"id":4348},"分布式锁",[928,4350,4351],{"id":4351},"简单实现",[899,4353,4355],{"className":933,"code":4354,"language":915,"meta":11,"style":11},"func TryLock(ctx context.Context, key string, value string, expiration time.Duration) bool {\n    ok, err := rdb.SetNX(ctx, key, value, expiration).Result()\n    if err != nil {\n        return false\n    }\n    return ok\n}\n\nfunc Unlock(ctx context.Context, key string, value string) bool {\n    \u002F\u002F 使用 Lua 脚本保证原子性\n    script := redis.NewScript(`\n        if redis.call('get', KEYS[1]) == ARGV[1] then\n            return redis.call('del', KEYS[1])\n        else\n            return 0\n        end\n    `)\n    result, err := script.Run(ctx, rdb, []string{key}, value).Int()\n    return err == nil && result == 1\n}\n\n\u002F\u002F 使用\nlockKey := \"lock:resource\"\nlockValue := uuid.New().String()\n\nif TryLock(ctx, lockKey, lockValue, time.Second*10) {\n    defer Unlock(ctx, lockKey, lockValue)\n    \u002F\u002F 执行业务逻辑\n}\n",[905,4356,4357,4412,4430,4442,4449,4453,4460,4464,4468,4503,4508,4523,4528,4533,4538,4543,4548,4555,4577,4597,4601,4605,4610,4620,4641,4645,4661,4671,4676],{"__ignoreMap":11},[908,4358,4359,4361,4364,4366,4369,4372,4374,4377,4379,4382,4385,4387,4390,4392,4394,4397,4400,4402,4405,4407,4410],{"class":910,"line":911},[908,4360,1013],{"class":941},[908,4362,4363],{"class":914}," TryLock",[908,4365,1037],{"class":945},[908,4367,4368],{"class":3909},"ctx",[908,4370,4371],{"class":914}," context",[908,4373,999],{"class":945},[908,4375,4376],{"class":914},"Context",[908,4378,1106],{"class":945},[908,4380,4381],{"class":3909},"key",[908,4383,4384],{"class":941}," string",[908,4386,1106],{"class":945},[908,4388,4389],{"class":3909},"value",[908,4391,4384],{"class":941},[908,4393,1106],{"class":945},[908,4395,4396],{"class":3909},"expiration",[908,4398,4399],{"class":914}," time",[908,4401,999],{"class":945},[908,4403,4404],{"class":914},"Duration",[908,4406,3921],{"class":945},[908,4408,4409],{"class":941},"bool",[908,4411,1185],{"class":945},[908,4413,4414,4417,4419,4421,4423,4426,4428],{"class":910,"line":949},[908,4415,4416],{"class":945},"    ok, err ",[908,4418,1136],{"class":941},[908,4420,1156],{"class":945},[908,4422,1491],{"class":914},[908,4424,4425],{"class":945},"(ctx, key, value, expiration).",[908,4427,1165],{"class":914},[908,4429,1145],{"class":945},[908,4431,4432,4434,4436,4438,4440],{"class":910,"line":961},[908,4433,1173],{"class":941},[908,4435,1176],{"class":945},[908,4437,1179],{"class":941},[908,4439,1182],{"class":1087},[908,4441,1185],{"class":945},[908,4443,4444,4446],{"class":910,"line":971},[908,4445,4076],{"class":941},[908,4447,4448],{"class":1087}," false\n",[908,4450,4451],{"class":910,"line":977},[908,4452,1200],{"class":945},[908,4454,4455,4457],{"class":910,"line":984},[908,4456,3972],{"class":941},[908,4458,4459],{"class":945}," ok\n",[908,4461,4462],{"class":910,"line":1005},[908,4463,1206],{"class":945},[908,4465,4466],{"class":910,"line":1010},[908,4467,981],{"emptyLinePlaceholder":980},[908,4469,4470,4472,4475,4477,4479,4481,4483,4485,4487,4489,4491,4493,4495,4497,4499,4501],{"class":910,"line":1022},[908,4471,1013],{"class":941},[908,4473,4474],{"class":914}," Unlock",[908,4476,1037],{"class":945},[908,4478,4368],{"class":3909},[908,4480,4371],{"class":914},[908,4482,999],{"class":945},[908,4484,4376],{"class":914},[908,4486,1106],{"class":945},[908,4488,4381],{"class":3909},[908,4490,4384],{"class":941},[908,4492,1106],{"class":945},[908,4494,4389],{"class":3909},[908,4496,4384],{"class":941},[908,4498,3921],{"class":945},[908,4500,4409],{"class":941},[908,4502,1185],{"class":945},[908,4504,4505],{"class":910,"line":1053},[908,4506,4507],{"class":1077},"    \u002F\u002F 使用 Lua 脚本保证原子性\n",[908,4509,4510,4513,4515,4517,4519,4521],{"class":910,"line":1065},[908,4511,4512],{"class":945},"    script ",[908,4514,1136],{"class":941},[908,4516,1031],{"class":945},[908,4518,4214],{"class":914},[908,4520,1037],{"class":945},[908,4522,4219],{"class":918},[908,4524,4525],{"class":910,"line":1081},[908,4526,4527],{"class":918},"        if redis.call('get', KEYS[1]) == ARGV[1] then\n",[908,4529,4530],{"class":910,"line":1097},[908,4531,4532],{"class":918},"            return redis.call('del', KEYS[1])\n",[908,4534,4535],{"class":910,"line":1112},[908,4536,4537],{"class":918},"        else\n",[908,4539,4540],{"class":910,"line":1118},[908,4541,4542],{"class":918},"            return 0\n",[908,4544,4545],{"class":910,"line":1124},[908,4546,4547],{"class":918},"        end\n",[908,4549,4550,4553],{"class":910,"line":1130},[908,4551,4552],{"class":918},"    `",[908,4554,974],{"class":945},[908,4556,4557,4560,4562,4564,4566,4568,4570,4573,4575],{"class":910,"line":1148},[908,4558,4559],{"class":945},"    result, err ",[908,4561,1136],{"class":941},[908,4563,4240],{"class":945},[908,4565,4243],{"class":914},[908,4567,4246],{"class":945},[908,4569,1247],{"class":941},[908,4571,4572],{"class":945},"{key}, value).",[908,4574,4050],{"class":914},[908,4576,1145],{"class":945},[908,4578,4579,4581,4583,4585,4587,4589,4592,4594],{"class":910,"line":1170},[908,4580,3972],{"class":941},[908,4582,1176],{"class":945},[908,4584,1580],{"class":941},[908,4586,1182],{"class":1087},[908,4588,4065],{"class":941},[908,4590,4591],{"class":945}," result ",[908,4593,1580],{"class":941},[908,4595,4596],{"class":1087}," 1\n",[908,4598,4599],{"class":910,"line":1188},[908,4600,1206],{"class":945},[908,4602,4603],{"class":910,"line":1197},[908,4604,981],{"emptyLinePlaceholder":980},[908,4606,4607],{"class":910,"line":1203},[908,4608,4609],{"class":1077},"\u002F\u002F 使用\n",[908,4611,4612,4615,4617],{"class":910,"line":1660},[908,4613,4614],{"class":945},"lockKey ",[908,4616,1136],{"class":941},[908,4618,4619],{"class":918}," \"lock:resource\"\n",[908,4621,4622,4625,4627,4630,4633,4636,4639],{"class":910,"line":1687},[908,4623,4624],{"class":945},"lockValue ",[908,4626,1136],{"class":941},[908,4628,4629],{"class":945}," uuid.",[908,4631,4632],{"class":914},"New",[908,4634,4635],{"class":945},"().",[908,4637,4638],{"class":914},"String",[908,4640,1145],{"class":945},[908,4642,4643],{"class":910,"line":1692},[908,4644,981],{"emptyLinePlaceholder":980},[908,4646,4647,4649,4651,4654,4656,4658],{"class":910,"line":1698},[908,4648,1575],{"class":941},[908,4650,4363],{"class":914},[908,4652,4653],{"class":945},"(ctx, lockKey, lockValue, time.Second",[908,4655,993],{"class":941},[908,4657,1740],{"class":1087},[908,4659,4660],{"class":945},") {\n",[908,4662,4663,4666,4668],{"class":910,"line":1722},[908,4664,4665],{"class":941},"    defer",[908,4667,4474],{"class":914},[908,4669,4670],{"class":945},"(ctx, lockKey, lockValue)\n",[908,4672,4673],{"class":910,"line":1749},[908,4674,4675],{"class":1077},"    \u002F\u002F 执行业务逻辑\n",[908,4677,4678],{"class":910,"line":1754},[908,4679,1206],{"class":945},[928,4681,4683],{"id":4682},"使用-redsync","使用 Redsync",[899,4685,4687],{"className":933,"code":4686,"language":915,"meta":11,"style":11},"import (\n    \"github.com\u002Fgo-redsync\u002Fredsync\u002Fv4\"\n    \"github.com\u002Fgo-redsync\u002Fredsync\u002Fv4\u002Fredis\u002Fgoredis\u002Fv9\"\n)\n\npool := goredis.NewPool(rdb)\nrs := redsync.New(pool)\n\nmutex := rs.NewMutex(\"lock:resource\",\n    redsync.WithExpiry(time.Second*10),\n    redsync.WithTries(3),\n)\n\nif err := mutex.Lock(); err != nil {\n    \u002F\u002F 获取锁失败\n    return err\n}\ndefer mutex.Unlock()\n\n\u002F\u002F 执行业务逻辑\n",[905,4688,4689,4695,4704,4713,4717,4721,4737,4752,4756,4776,4794,4808,4812,4816,4839,4844,4850,4854,4866,4870],{"__ignoreMap":11},[908,4690,4691,4693],{"class":910,"line":911},[908,4692,942],{"class":941},[908,4694,946],{"class":945},[908,4696,4697,4699,4702],{"class":910,"line":949},[908,4698,952],{"class":918},[908,4700,4701],{"class":914},"github.com\u002Fgo-redsync\u002Fredsync\u002Fv4",[908,4703,958],{"class":918},[908,4705,4706,4708,4711],{"class":910,"line":961},[908,4707,952],{"class":918},[908,4709,4710],{"class":914},"github.com\u002Fgo-redsync\u002Fredsync\u002Fv4\u002Fredis\u002Fgoredis\u002Fv9",[908,4712,958],{"class":918},[908,4714,4715],{"class":910,"line":971},[908,4716,974],{"class":945},[908,4718,4719],{"class":910,"line":977},[908,4720,981],{"emptyLinePlaceholder":980},[908,4722,4723,4726,4728,4731,4734],{"class":910,"line":984},[908,4724,4725],{"class":945},"pool ",[908,4727,1136],{"class":941},[908,4729,4730],{"class":945}," goredis.",[908,4732,4733],{"class":914},"NewPool",[908,4735,4736],{"class":945},"(rdb)\n",[908,4738,4739,4742,4744,4747,4749],{"class":910,"line":1005},[908,4740,4741],{"class":945},"rs ",[908,4743,1136],{"class":941},[908,4745,4746],{"class":945}," redsync.",[908,4748,4632],{"class":914},[908,4750,4751],{"class":945},"(pool)\n",[908,4753,4754],{"class":910,"line":1010},[908,4755,981],{"emptyLinePlaceholder":980},[908,4757,4758,4761,4763,4766,4769,4771,4774],{"class":910,"line":1022},[908,4759,4760],{"class":945},"mutex ",[908,4762,1136],{"class":941},[908,4764,4765],{"class":945}," rs.",[908,4767,4768],{"class":914},"NewMutex",[908,4770,1037],{"class":945},[908,4772,4773],{"class":918},"\"lock:resource\"",[908,4775,1062],{"class":945},[908,4777,4778,4781,4784,4787,4789,4791],{"class":910,"line":1053},[908,4779,4780],{"class":945},"    redsync.",[908,4782,4783],{"class":914},"WithExpiry",[908,4785,4786],{"class":945},"(time.Second",[908,4788,993],{"class":941},[908,4790,1740],{"class":1087},[908,4792,4793],{"class":945},"),\n",[908,4795,4796,4798,4801,4803,4806],{"class":910,"line":1065},[908,4797,4780],{"class":945},[908,4799,4800],{"class":914},"WithTries",[908,4802,1037],{"class":945},[908,4804,4805],{"class":1087},"3",[908,4807,4793],{"class":945},[908,4809,4810],{"class":910,"line":1081},[908,4811,974],{"class":945},[908,4813,4814],{"class":910,"line":1097},[908,4815,981],{"emptyLinePlaceholder":980},[908,4817,4818,4820,4822,4824,4827,4830,4833,4835,4837],{"class":910,"line":1112},[908,4819,1575],{"class":941},[908,4821,1176],{"class":945},[908,4823,1136],{"class":941},[908,4825,4826],{"class":945}," mutex.",[908,4828,4829],{"class":914},"Lock",[908,4831,4832],{"class":945},"(); err ",[908,4834,1179],{"class":941},[908,4836,1182],{"class":1087},[908,4838,1185],{"class":945},[908,4840,4841],{"class":910,"line":1118},[908,4842,4843],{"class":1077},"    \u002F\u002F 获取锁失败\n",[908,4845,4846,4848],{"class":910,"line":1124},[908,4847,3972],{"class":941},[908,4849,4079],{"class":945},[908,4851,4852],{"class":910,"line":1130},[908,4853,1206],{"class":945},[908,4855,4856,4859,4861,4864],{"class":910,"line":1148},[908,4857,4858],{"class":941},"defer",[908,4860,4826],{"class":945},[908,4862,4863],{"class":914},"Unlock",[908,4865,1145],{"class":945},[908,4867,4868],{"class":910,"line":1170},[908,4869,981],{"emptyLinePlaceholder":980},[908,4871,4872],{"class":910,"line":1188},[908,4873,4874],{"class":1077},"\u002F\u002F 执行业务逻辑\n",[895,4876,4877],{"id":4877},"缓存模式",[928,4879,4881],{"id":4880},"cache-aside","Cache Aside",[899,4883,4885],{"className":933,"code":4884,"language":915,"meta":11,"style":11},"func GetUser(ctx context.Context, userID int) (*User, error) {\n    \u002F\u002F 1. 先查缓存\n    key := fmt.Sprintf(\"user:%d\", userID)\n    val, err := rdb.Get(ctx, key).Result()\n    if err == nil {\n        var user User\n        json.Unmarshal([]byte(val), &user)\n        return &user, nil\n    }\n    \n    \u002F\u002F 2. 缓存未命中，查数据库\n    user, err := db.GetUserByID(userID)\n    if err != nil {\n        return nil, err\n    }\n    \n    \u002F\u002F 3. 写入缓存\n    data, _ := json.Marshal(user)\n    rdb.Set(ctx, key, data, time.Hour)\n    \n    return user, nil\n}\n\nfunc UpdateUser(ctx context.Context, user *User) error {\n    \u002F\u002F 1. 更新数据库\n    if err := db.UpdateUser(user); err != nil {\n        return err\n    }\n    \n    \u002F\u002F 2. 删除缓存\n    key := fmt.Sprintf(\"user:%d\", user.ID)\n    rdb.Del(ctx, key)\n    \n    return nil\n}\n",[905,4886,4887,4926,4931,4958,4976,4988,4999,5021,5034,5038,5042,5047,5063,5075,5084,5088,5092,5097,5113,5123,5127,5136,5140,5144,5176,5181,5203,5209,5213,5217,5222,5243,5253,5257,5263],{"__ignoreMap":11},[908,4888,4889,4891,4894,4896,4898,4900,4902,4904,4906,4909,4912,4915,4917,4920,4922,4924],{"class":910,"line":911},[908,4890,1013],{"class":941},[908,4892,4893],{"class":914}," GetUser",[908,4895,1037],{"class":945},[908,4897,4368],{"class":3909},[908,4899,4371],{"class":914},[908,4901,999],{"class":945},[908,4903,4376],{"class":914},[908,4905,1106],{"class":945},[908,4907,4908],{"class":3909},"userID",[908,4910,4911],{"class":941}," int",[908,4913,4914],{"class":945},") (",[908,4916,993],{"class":941},[908,4918,4919],{"class":914},"User",[908,4921,1106],{"class":945},[908,4923,3924],{"class":941},[908,4925,4660],{"class":945},[908,4927,4928],{"class":910,"line":949},[908,4929,4930],{"class":1077},"    \u002F\u002F 1. 先查缓存\n",[908,4932,4933,4936,4938,4941,4944,4946,4949,4952,4955],{"class":910,"line":961},[908,4934,4935],{"class":945},"    key ",[908,4937,1136],{"class":941},[908,4939,4940],{"class":945}," fmt.",[908,4942,4943],{"class":914},"Sprintf",[908,4945,1037],{"class":945},[908,4947,4948],{"class":918},"\"user:",[908,4950,4951],{"class":1087},"%d",[908,4953,4954],{"class":918},"\"",[908,4956,4957],{"class":945},", userID)\n",[908,4959,4960,4963,4965,4967,4969,4972,4974],{"class":910,"line":971},[908,4961,4962],{"class":945},"    val, err ",[908,4964,1136],{"class":941},[908,4966,1156],{"class":945},[908,4968,1560],{"class":914},[908,4970,4971],{"class":945},"(ctx, key).",[908,4973,1165],{"class":914},[908,4975,1145],{"class":945},[908,4977,4978,4980,4982,4984,4986],{"class":910,"line":977},[908,4979,1173],{"class":941},[908,4981,1176],{"class":945},[908,4983,1580],{"class":941},[908,4985,1182],{"class":1087},[908,4987,1185],{"class":945},[908,4989,4990,4993,4996],{"class":910,"line":984},[908,4991,4992],{"class":941},"        var",[908,4994,4995],{"class":945}," user ",[908,4997,4998],{"class":914},"User\n",[908,5000,5001,5004,5007,5010,5013,5016,5018],{"class":910,"line":1005},[908,5002,5003],{"class":945},"        json.",[908,5005,5006],{"class":914},"Unmarshal",[908,5008,5009],{"class":945},"([]",[908,5011,5012],{"class":941},"byte",[908,5014,5015],{"class":945},"(val), ",[908,5017,1040],{"class":941},[908,5019,5020],{"class":945},"user)\n",[908,5022,5023,5025,5028,5031],{"class":910,"line":1010},[908,5024,4076],{"class":941},[908,5026,5027],{"class":941}," &",[908,5029,5030],{"class":945},"user, ",[908,5032,5033],{"class":1087},"nil\n",[908,5035,5036],{"class":910,"line":1022},[908,5037,1200],{"class":945},[908,5039,5040],{"class":910,"line":1053},[908,5041,1121],{"class":945},[908,5043,5044],{"class":910,"line":1065},[908,5045,5046],{"class":1077},"    \u002F\u002F 2. 缓存未命中，查数据库\n",[908,5048,5049,5052,5054,5057,5060],{"class":910,"line":1081},[908,5050,5051],{"class":945},"    user, err ",[908,5053,1136],{"class":941},[908,5055,5056],{"class":945}," db.",[908,5058,5059],{"class":914},"GetUserByID",[908,5061,5062],{"class":945},"(userID)\n",[908,5064,5065,5067,5069,5071,5073],{"class":910,"line":1097},[908,5066,1173],{"class":941},[908,5068,1176],{"class":945},[908,5070,1179],{"class":941},[908,5072,1182],{"class":1087},[908,5074,1185],{"class":945},[908,5076,5077,5079,5081],{"class":910,"line":1112},[908,5078,4076],{"class":941},[908,5080,1182],{"class":1087},[908,5082,5083],{"class":945},", err\n",[908,5085,5086],{"class":910,"line":1118},[908,5087,1200],{"class":945},[908,5089,5090],{"class":910,"line":1124},[908,5091,1121],{"class":945},[908,5093,5094],{"class":910,"line":1130},[908,5095,5096],{"class":1077},"    \u002F\u002F 3. 写入缓存\n",[908,5098,5099,5102,5104,5107,5110],{"class":910,"line":1148},[908,5100,5101],{"class":945},"    data, _ ",[908,5103,1136],{"class":941},[908,5105,5106],{"class":945}," json.",[908,5108,5109],{"class":914},"Marshal",[908,5111,5112],{"class":945},"(user)\n",[908,5114,5115,5118,5120],{"class":910,"line":1170},[908,5116,5117],{"class":945},"    rdb.",[908,5119,1415],{"class":914},[908,5121,5122],{"class":945},"(ctx, key, data, time.Hour)\n",[908,5124,5125],{"class":910,"line":1188},[908,5126,1121],{"class":945},[908,5128,5129,5131,5134],{"class":910,"line":1197},[908,5130,3972],{"class":941},[908,5132,5133],{"class":945}," user, ",[908,5135,5033],{"class":1087},[908,5137,5138],{"class":910,"line":1203},[908,5139,1206],{"class":945},[908,5141,5142],{"class":910,"line":1660},[908,5143,981],{"emptyLinePlaceholder":980},[908,5145,5146,5148,5151,5153,5155,5157,5159,5161,5163,5166,5168,5170,5172,5174],{"class":910,"line":1687},[908,5147,1013],{"class":941},[908,5149,5150],{"class":914}," UpdateUser",[908,5152,1037],{"class":945},[908,5154,4368],{"class":3909},[908,5156,4371],{"class":914},[908,5158,999],{"class":945},[908,5160,4376],{"class":914},[908,5162,1106],{"class":945},[908,5164,5165],{"class":3909},"user",[908,5167,4011],{"class":941},[908,5169,4919],{"class":914},[908,5171,3921],{"class":945},[908,5173,3924],{"class":941},[908,5175,1185],{"class":945},[908,5177,5178],{"class":910,"line":1692},[908,5179,5180],{"class":1077},"    \u002F\u002F 1. 更新数据库\n",[908,5182,5183,5185,5187,5189,5191,5194,5197,5199,5201],{"class":910,"line":1698},[908,5184,1173],{"class":941},[908,5186,1176],{"class":945},[908,5188,1136],{"class":941},[908,5190,5056],{"class":945},[908,5192,5193],{"class":914},"UpdateUser",[908,5195,5196],{"class":945},"(user); err ",[908,5198,1179],{"class":941},[908,5200,1182],{"class":1087},[908,5202,1185],{"class":945},[908,5204,5205,5207],{"class":910,"line":1722},[908,5206,4076],{"class":941},[908,5208,4079],{"class":945},[908,5210,5211],{"class":910,"line":1749},[908,5212,1200],{"class":945},[908,5214,5215],{"class":910,"line":1754},[908,5216,1121],{"class":945},[908,5218,5219],{"class":910,"line":1760},[908,5220,5221],{"class":1077},"    \u002F\u002F 2. 删除缓存\n",[908,5223,5224,5226,5228,5230,5232,5234,5236,5238,5240],{"class":910,"line":1782},[908,5225,4935],{"class":945},[908,5227,1136],{"class":941},[908,5229,4940],{"class":945},[908,5231,4943],{"class":914},[908,5233,1037],{"class":945},[908,5235,4948],{"class":918},[908,5237,4951],{"class":1087},[908,5239,4954],{"class":918},[908,5241,5242],{"class":945},", user.ID)\n",[908,5244,5245,5247,5250],{"class":910,"line":1808},[908,5246,5117],{"class":945},[908,5248,5249],{"class":914},"Del",[908,5251,5252],{"class":945},"(ctx, key)\n",[908,5254,5255],{"class":910,"line":1813},[908,5256,1121],{"class":945},[908,5258,5259,5261],{"class":910,"line":1819},[908,5260,3972],{"class":941},[908,5262,3975],{"class":1087},[908,5264,5265],{"class":910,"line":1847},[908,5266,1206],{"class":945},[928,5268,5270],{"id":5269},"缓存穿透布隆过滤器","缓存穿透（布隆过滤器）",[899,5272,5274],{"className":933,"code":5273,"language":915,"meta":11,"style":11},"import \"github.com\u002Fbits-and-blooms\u002Fbloom\u002Fv3\"\n\nvar filter *bloom.BloomFilter\n\nfunc init() {\n    \u002F\u002F 创建布隆过滤器\n    filter = bloom.NewWithEstimates(1000000, 0.01)\n    \n    \u002F\u002F 加载已有数据\n    users, _ := db.GetAllUserIDs()\n    for _, id := range users {\n        filter.AddString(fmt.Sprintf(\"%d\", id))\n    }\n}\n\nfunc GetUser(ctx context.Context, userID int) (*User, error) {\n    \u002F\u002F 先检查布隆过滤器\n    if !filter.TestString(fmt.Sprintf(\"%d\", userID)) {\n        return nil, errors.New(\"用户不存在\")\n    }\n    \n    \u002F\u002F 查缓存和数据库...\n}\n",[905,5275,5276,5288,5292,5309,5313,5322,5327,5352,5356,5361,5375,5390,5414,5418,5422,5426,5460,5465,5493,5511,5515,5519,5524],{"__ignoreMap":11},[908,5277,5278,5280,5283,5286],{"class":910,"line":911},[908,5279,942],{"class":941},[908,5281,5282],{"class":918}," \"",[908,5284,5285],{"class":914},"github.com\u002Fbits-and-blooms\u002Fbloom\u002Fv3",[908,5287,958],{"class":918},[908,5289,5290],{"class":910,"line":949},[908,5291,981],{"emptyLinePlaceholder":980},[908,5293,5294,5296,5299,5301,5304,5306],{"class":910,"line":961},[908,5295,987],{"class":941},[908,5297,5298],{"class":945}," filter ",[908,5300,993],{"class":941},[908,5302,5303],{"class":914},"bloom",[908,5305,999],{"class":945},[908,5307,5308],{"class":914},"BloomFilter\n",[908,5310,5311],{"class":910,"line":971},[908,5312,981],{"emptyLinePlaceholder":980},[908,5314,5315,5317,5320],{"class":910,"line":977},[908,5316,1013],{"class":941},[908,5318,5319],{"class":914}," init",[908,5321,1019],{"class":945},[908,5323,5324],{"class":910,"line":984},[908,5325,5326],{"class":1077},"    \u002F\u002F 创建布隆过滤器\n",[908,5328,5329,5332,5334,5337,5340,5342,5345,5347,5350],{"class":910,"line":1005},[908,5330,5331],{"class":945},"    filter ",[908,5333,1028],{"class":941},[908,5335,5336],{"class":945}," bloom.",[908,5338,5339],{"class":914},"NewWithEstimates",[908,5341,1037],{"class":945},[908,5343,5344],{"class":1087},"1000000",[908,5346,1106],{"class":945},[908,5348,5349],{"class":1087},"0.01",[908,5351,974],{"class":945},[908,5353,5354],{"class":910,"line":1010},[908,5355,1121],{"class":945},[908,5357,5358],{"class":910,"line":1022},[908,5359,5360],{"class":1077},"    \u002F\u002F 加载已有数据\n",[908,5362,5363,5366,5368,5370,5373],{"class":910,"line":1053},[908,5364,5365],{"class":945},"    users, _ ",[908,5367,1136],{"class":941},[908,5369,5056],{"class":945},[908,5371,5372],{"class":914},"GetAllUserIDs",[908,5374,1145],{"class":945},[908,5376,5377,5380,5383,5385,5387],{"class":910,"line":1065},[908,5378,5379],{"class":941},"    for",[908,5381,5382],{"class":945}," _, id ",[908,5384,1136],{"class":941},[908,5386,3826],{"class":941},[908,5388,5389],{"class":945}," users {\n",[908,5391,5392,5395,5398,5401,5403,5405,5407,5409,5411],{"class":910,"line":1081},[908,5393,5394],{"class":945},"        filter.",[908,5396,5397],{"class":914},"AddString",[908,5399,5400],{"class":945},"(fmt.",[908,5402,4943],{"class":914},[908,5404,1037],{"class":945},[908,5406,4954],{"class":918},[908,5408,4951],{"class":1087},[908,5410,4954],{"class":918},[908,5412,5413],{"class":945},", id))\n",[908,5415,5416],{"class":910,"line":1097},[908,5417,1200],{"class":945},[908,5419,5420],{"class":910,"line":1112},[908,5421,1206],{"class":945},[908,5423,5424],{"class":910,"line":1118},[908,5425,981],{"emptyLinePlaceholder":980},[908,5427,5428,5430,5432,5434,5436,5438,5440,5442,5444,5446,5448,5450,5452,5454,5456,5458],{"class":910,"line":1124},[908,5429,1013],{"class":941},[908,5431,4893],{"class":914},[908,5433,1037],{"class":945},[908,5435,4368],{"class":3909},[908,5437,4371],{"class":914},[908,5439,999],{"class":945},[908,5441,4376],{"class":914},[908,5443,1106],{"class":945},[908,5445,4908],{"class":3909},[908,5447,4911],{"class":941},[908,5449,4914],{"class":945},[908,5451,993],{"class":941},[908,5453,4919],{"class":914},[908,5455,1106],{"class":945},[908,5457,3924],{"class":941},[908,5459,4660],{"class":945},[908,5461,5462],{"class":910,"line":1130},[908,5463,5464],{"class":1077},"    \u002F\u002F 先检查布隆过滤器\n",[908,5466,5467,5469,5472,5475,5478,5480,5482,5484,5486,5488,5490],{"class":910,"line":1148},[908,5468,1173],{"class":941},[908,5470,5471],{"class":941}," !",[908,5473,5474],{"class":945},"filter.",[908,5476,5477],{"class":914},"TestString",[908,5479,5400],{"class":945},[908,5481,4943],{"class":914},[908,5483,1037],{"class":945},[908,5485,4954],{"class":918},[908,5487,4951],{"class":1087},[908,5489,4954],{"class":918},[908,5491,5492],{"class":945},", userID)) {\n",[908,5494,5495,5497,5499,5502,5504,5506,5509],{"class":910,"line":1170},[908,5496,4076],{"class":941},[908,5498,1182],{"class":1087},[908,5500,5501],{"class":945},", errors.",[908,5503,4632],{"class":914},[908,5505,1037],{"class":945},[908,5507,5508],{"class":918},"\"用户不存在\"",[908,5510,974],{"class":945},[908,5512,5513],{"class":910,"line":1188},[908,5514,1200],{"class":945},[908,5516,5517],{"class":910,"line":1197},[908,5518,1121],{"class":945},[908,5520,5521],{"class":910,"line":1203},[908,5522,5523],{"class":1077},"    \u002F\u002F 查缓存和数据库...\n",[908,5525,5526],{"class":910,"line":1660},[908,5527,1206],{"class":945},[928,5529,5531],{"id":5530},"缓存击穿互斥锁","缓存击穿（互斥锁）",[899,5533,5535],{"className":933,"code":5534,"language":915,"meta":11,"style":11},"func GetUserWithLock(ctx context.Context, userID int) (*User, error) {\n    key := fmt.Sprintf(\"user:%d\", userID)\n    lockKey := fmt.Sprintf(\"lock:user:%d\", userID)\n    \n    \u002F\u002F 1. 查缓存\n    val, err := rdb.Get(ctx, key).Result()\n    if err == nil {\n        var user User\n        json.Unmarshal([]byte(val), &user)\n        return &user, nil\n    }\n    \n    \u002F\u002F 2. 获取锁\n    lockValue := uuid.New().String()\n    if !TryLock(ctx, lockKey, lockValue, time.Second*3) {\n        \u002F\u002F 获取锁失败，等待后重试\n        time.Sleep(time.Millisecond * 100)\n        return GetUserWithLock(ctx, userID)\n    }\n    defer Unlock(ctx, lockKey, lockValue)\n    \n    \u002F\u002F 3. 双重检查\n    val, err = rdb.Get(ctx, key).Result()\n    if err == nil {\n        var user User\n        json.Unmarshal([]byte(val), &user)\n        return &user, nil\n    }\n    \n    \u002F\u002F 4. 查数据库并写缓存\n    user, err := db.GetUserByID(userID)\n    if err != nil {\n        return nil, err\n    }\n    \n    data, _ := json.Marshal(user)\n    rdb.Set(ctx, key, data, time.Hour)\n    \n    return user, nil\n}\n",[905,5536,5537,5572,5592,5614,5618,5623,5639,5651,5659,5675,5685,5689,5693,5698,5715,5732,5737,5755,5764,5768,5776,5780,5785,5801,5813,5821,5837,5847,5851,5855,5860,5872,5884,5892,5896,5900,5912,5920,5924,5932],{"__ignoreMap":11},[908,5538,5539,5541,5544,5546,5548,5550,5552,5554,5556,5558,5560,5562,5564,5566,5568,5570],{"class":910,"line":911},[908,5540,1013],{"class":941},[908,5542,5543],{"class":914}," GetUserWithLock",[908,5545,1037],{"class":945},[908,5547,4368],{"class":3909},[908,5549,4371],{"class":914},[908,5551,999],{"class":945},[908,5553,4376],{"class":914},[908,5555,1106],{"class":945},[908,5557,4908],{"class":3909},[908,5559,4911],{"class":941},[908,5561,4914],{"class":945},[908,5563,993],{"class":941},[908,5565,4919],{"class":914},[908,5567,1106],{"class":945},[908,5569,3924],{"class":941},[908,5571,4660],{"class":945},[908,5573,5574,5576,5578,5580,5582,5584,5586,5588,5590],{"class":910,"line":949},[908,5575,4935],{"class":945},[908,5577,1136],{"class":941},[908,5579,4940],{"class":945},[908,5581,4943],{"class":914},[908,5583,1037],{"class":945},[908,5585,4948],{"class":918},[908,5587,4951],{"class":1087},[908,5589,4954],{"class":918},[908,5591,4957],{"class":945},[908,5593,5594,5597,5599,5601,5603,5605,5608,5610,5612],{"class":910,"line":961},[908,5595,5596],{"class":945},"    lockKey ",[908,5598,1136],{"class":941},[908,5600,4940],{"class":945},[908,5602,4943],{"class":914},[908,5604,1037],{"class":945},[908,5606,5607],{"class":918},"\"lock:user:",[908,5609,4951],{"class":1087},[908,5611,4954],{"class":918},[908,5613,4957],{"class":945},[908,5615,5616],{"class":910,"line":971},[908,5617,1121],{"class":945},[908,5619,5620],{"class":910,"line":977},[908,5621,5622],{"class":1077},"    \u002F\u002F 1. 查缓存\n",[908,5624,5625,5627,5629,5631,5633,5635,5637],{"class":910,"line":984},[908,5626,4962],{"class":945},[908,5628,1136],{"class":941},[908,5630,1156],{"class":945},[908,5632,1560],{"class":914},[908,5634,4971],{"class":945},[908,5636,1165],{"class":914},[908,5638,1145],{"class":945},[908,5640,5641,5643,5645,5647,5649],{"class":910,"line":1005},[908,5642,1173],{"class":941},[908,5644,1176],{"class":945},[908,5646,1580],{"class":941},[908,5648,1182],{"class":1087},[908,5650,1185],{"class":945},[908,5652,5653,5655,5657],{"class":910,"line":1010},[908,5654,4992],{"class":941},[908,5656,4995],{"class":945},[908,5658,4998],{"class":914},[908,5660,5661,5663,5665,5667,5669,5671,5673],{"class":910,"line":1022},[908,5662,5003],{"class":945},[908,5664,5006],{"class":914},[908,5666,5009],{"class":945},[908,5668,5012],{"class":941},[908,5670,5015],{"class":945},[908,5672,1040],{"class":941},[908,5674,5020],{"class":945},[908,5676,5677,5679,5681,5683],{"class":910,"line":1053},[908,5678,4076],{"class":941},[908,5680,5027],{"class":941},[908,5682,5030],{"class":945},[908,5684,5033],{"class":1087},[908,5686,5687],{"class":910,"line":1065},[908,5688,1200],{"class":945},[908,5690,5691],{"class":910,"line":1081},[908,5692,1121],{"class":945},[908,5694,5695],{"class":910,"line":1097},[908,5696,5697],{"class":1077},"    \u002F\u002F 2. 获取锁\n",[908,5699,5700,5703,5705,5707,5709,5711,5713],{"class":910,"line":1112},[908,5701,5702],{"class":945},"    lockValue ",[908,5704,1136],{"class":941},[908,5706,4629],{"class":945},[908,5708,4632],{"class":914},[908,5710,4635],{"class":945},[908,5712,4638],{"class":914},[908,5714,1145],{"class":945},[908,5716,5717,5719,5721,5724,5726,5728,5730],{"class":910,"line":1118},[908,5718,1173],{"class":941},[908,5720,5471],{"class":941},[908,5722,5723],{"class":914},"TryLock",[908,5725,4653],{"class":945},[908,5727,993],{"class":941},[908,5729,4805],{"class":1087},[908,5731,4660],{"class":945},[908,5733,5734],{"class":910,"line":1124},[908,5735,5736],{"class":1077},"        \u002F\u002F 获取锁失败，等待后重试\n",[908,5738,5739,5742,5745,5748,5750,5753],{"class":910,"line":1130},[908,5740,5741],{"class":945},"        time.",[908,5743,5744],{"class":914},"Sleep",[908,5746,5747],{"class":945},"(time.Millisecond ",[908,5749,993],{"class":941},[908,5751,5752],{"class":1087}," 100",[908,5754,974],{"class":945},[908,5756,5757,5759,5761],{"class":910,"line":1148},[908,5758,4076],{"class":941},[908,5760,5543],{"class":914},[908,5762,5763],{"class":945},"(ctx, userID)\n",[908,5765,5766],{"class":910,"line":1170},[908,5767,1200],{"class":945},[908,5769,5770,5772,5774],{"class":910,"line":1188},[908,5771,4665],{"class":941},[908,5773,4474],{"class":914},[908,5775,4670],{"class":945},[908,5777,5778],{"class":910,"line":1197},[908,5779,1121],{"class":945},[908,5781,5782],{"class":910,"line":1203},[908,5783,5784],{"class":1077},"    \u002F\u002F 3. 双重检查\n",[908,5786,5787,5789,5791,5793,5795,5797,5799],{"class":910,"line":1660},[908,5788,4962],{"class":945},[908,5790,1028],{"class":941},[908,5792,1156],{"class":945},[908,5794,1560],{"class":914},[908,5796,4971],{"class":945},[908,5798,1165],{"class":914},[908,5800,1145],{"class":945},[908,5802,5803,5805,5807,5809,5811],{"class":910,"line":1687},[908,5804,1173],{"class":941},[908,5806,1176],{"class":945},[908,5808,1580],{"class":941},[908,5810,1182],{"class":1087},[908,5812,1185],{"class":945},[908,5814,5815,5817,5819],{"class":910,"line":1692},[908,5816,4992],{"class":941},[908,5818,4995],{"class":945},[908,5820,4998],{"class":914},[908,5822,5823,5825,5827,5829,5831,5833,5835],{"class":910,"line":1698},[908,5824,5003],{"class":945},[908,5826,5006],{"class":914},[908,5828,5009],{"class":945},[908,5830,5012],{"class":941},[908,5832,5015],{"class":945},[908,5834,1040],{"class":941},[908,5836,5020],{"class":945},[908,5838,5839,5841,5843,5845],{"class":910,"line":1722},[908,5840,4076],{"class":941},[908,5842,5027],{"class":941},[908,5844,5030],{"class":945},[908,5846,5033],{"class":1087},[908,5848,5849],{"class":910,"line":1749},[908,5850,1200],{"class":945},[908,5852,5853],{"class":910,"line":1754},[908,5854,1121],{"class":945},[908,5856,5857],{"class":910,"line":1760},[908,5858,5859],{"class":1077},"    \u002F\u002F 4. 查数据库并写缓存\n",[908,5861,5862,5864,5866,5868,5870],{"class":910,"line":1782},[908,5863,5051],{"class":945},[908,5865,1136],{"class":941},[908,5867,5056],{"class":945},[908,5869,5059],{"class":914},[908,5871,5062],{"class":945},[908,5873,5874,5876,5878,5880,5882],{"class":910,"line":1808},[908,5875,1173],{"class":941},[908,5877,1176],{"class":945},[908,5879,1179],{"class":941},[908,5881,1182],{"class":1087},[908,5883,1185],{"class":945},[908,5885,5886,5888,5890],{"class":910,"line":1813},[908,5887,4076],{"class":941},[908,5889,1182],{"class":1087},[908,5891,5083],{"class":945},[908,5893,5894],{"class":910,"line":1819},[908,5895,1200],{"class":945},[908,5897,5898],{"class":910,"line":1847},[908,5899,1121],{"class":945},[908,5901,5902,5904,5906,5908,5910],{"class":910,"line":1852},[908,5903,5101],{"class":945},[908,5905,1136],{"class":941},[908,5907,5106],{"class":945},[908,5909,5109],{"class":914},[908,5911,5112],{"class":945},[908,5913,5914,5916,5918],{"class":910,"line":1858},[908,5915,5117],{"class":945},[908,5917,1415],{"class":914},[908,5919,5122],{"class":945},[908,5921,5922],{"class":910,"line":2313},[908,5923,1121],{"class":945},[908,5925,5926,5928,5930],{"class":910,"line":3578},[908,5927,3972],{"class":941},[908,5929,5133],{"class":945},[908,5931,5033],{"class":1087},[908,5933,5934],{"class":910,"line":3583},[908,5935,1206],{"class":945},[5937,5938,5939],"style",{},"html pre.shiki code .snPdu, html code.shiki .snPdu{--shiki-light:#6F42C1;--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .sIIMD, html code.shiki .sIIMD{--shiki-light:#032F62;--shiki-default:#032F62;--shiki-dark:#9ECBFF}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}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 .s8jYJ, html code.shiki .s8jYJ{--shiki-light:#D73A49;--shiki-default:#D73A49;--shiki-dark:#F97583}html pre.shiki code .sxrX7, html code.shiki .sxrX7{--shiki-light:#24292E;--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .sCsY4, html code.shiki .sCsY4{--shiki-light:#6A737D;--shiki-default:#6A737D;--shiki-dark:#6A737D}html pre.shiki code .sBjJW, html code.shiki .sBjJW{--shiki-light:#005CC5;--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .sP4rz, html code.shiki .sP4rz{--shiki-light:#E36209;--shiki-default:#E36209;--shiki-dark:#FFAB70}",{"title":11,"searchDepth":949,"depth":949,"links":5941},[5942,5943,5948,5955,5960,5964],{"id":897,"depth":949,"text":897},{"id":925,"depth":949,"text":926,"children":5944},[5945,5946,5947],{"id":930,"depth":961,"text":930},{"id":1209,"depth":961,"text":1209},{"id":1292,"depth":961,"text":1292},{"id":1372,"depth":949,"text":1372,"children":5949},[5950,5951,5952,5953,5954],{"id":1375,"depth":961,"text":1376},{"id":1880,"depth":961,"text":1881},{"id":2335,"depth":961,"text":2336},{"id":2754,"depth":961,"text":2755},{"id":3111,"depth":961,"text":3112},{"id":3651,"depth":949,"text":3651,"children":5956},[5957,5958,5959],{"id":3654,"depth":961,"text":3655},{"id":3862,"depth":961,"text":3862},{"id":4175,"depth":961,"text":4176},{"id":4348,"depth":949,"text":4348,"children":5961},[5962,5963],{"id":4351,"depth":961,"text":4351},{"id":4682,"depth":961,"text":4683},{"id":4877,"depth":949,"text":4877,"children":5965},[5966,5967,5968],{"id":4880,"depth":961,"text":4881},{"id":5269,"depth":961,"text":5270},{"id":5530,"depth":961,"text":5531},"md",{},{"title":196,"description":197},"golang\u002Fdistributed\u002Fredis","n6dFXm-_N5bXpoC4Wl8n7q5-89BXL7hkQTfzOvqZN4g",1775496424252]