diff --git a/.gitignore b/.gitignore index d45b03e..08c2848 100644 --- a/.gitignore +++ b/.gitignore @@ -11,6 +11,8 @@ venv/ # Build .next/ +.next-dev/ +.next-prod/ dist/ build/ *.egg-info/ diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 0000000..20a690a --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,84 @@ +# CLAUDE.md + +This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. + +## 项目概述 + +AI 翻译网站 - Monorepo 架构,前端 Next.js + 后端 FastAPI,支持流式输出(SSE)、Redis 缓存/限流、PostgreSQL 数据存储。 + +## 常用命令 + +### 后端开发 (apps/api) + +```bash +cd apps/api +pip install -e . # 安装依赖 +pip install -e ".[dev]" # 安装开发依赖 +uvicorn app.main:app --reload # 启动开发服务器 (localhost:8000) +python scripts/init_db.py [用户名] [密码] # 初始化数据库管理员账户 + +# 测试与代码检查 +pytest # 运行测试 +ruff check . # 代码检查 +ruff format . # 代码格式化 +``` + +### 前端开发 (apps/web) + +```bash +cd apps/web +npm install # 安装依赖 +npm run dev # 启动开发服务器 (localhost:3000) +npm run build # 构建生产版本 +npm run lint # ESLint 检查 +``` + +### Docker 部署 (infra) + +```bash +cd infra +cp .env.example .env # 配置环境变量 +docker-compose up -d # 启动所有服务 +``` + +## 架构概览 + +``` +apps/ + web/ # Next.js 14 前端 (TypeScript + Tailwind CSS) + api/ # FastAPI 后端 (Python 3.11+, async) +infra/ # Docker Compose 配置 +``` + +### 后端结构 (apps/api/app) + +- `main.py` - FastAPI 应用入口,配置中间件和路由 +- `core/` - 配置(config.py)、日志(logging.py)、数据库(database.py) +- `api/` - 路由层:translate.py(翻译)、admin.py(管理)、ai_provider.py、stats.py +- `services/` - 业务逻辑:llm.py(LLM调用)、cache.py(Redis缓存)、rate_limit.py(限流)、auth.py、stats.py +- `schemas/` - Pydantic 请求/响应模型 +- `models/` - SQLAlchemy ORM 模型 + +### 核心 API 端点 + +- `POST /api/v1/translate` - 非流式翻译 +- `POST /api/v1/translate/stream` - SSE 流式翻译 +- `GET /health` - 健康检查 + +### 数据流 + +1. 请求 → 限流检查(Redis) → 缓存查询(Redis) +2. 缓存命中 → 直接返回 +3. 缓存未命中 → LLM 调用 → 写入缓存 → 返回 + +## 环境变量 + +后端 `.env` 关键配置: +- `LLM_API_KEY` - LLM 服务 API Key(必需) +- `LLM_MODEL` - 模型名称(默认 gpt-4o-mini) +- `LLM_BASE_URL` - 自定义 API 地址(可选) +- `DATABASE_URL` - MySQL 连接串 +- `REDIS_URL` - Redis 连接串 + +前端 `.env.local`: +- `NEXT_PUBLIC_API_BASE_URL` - 后端 API 地址 diff --git a/README.md b/README.md index d591417..d9dfe12 100644 --- a/README.md +++ b/README.md @@ -32,6 +32,13 @@ cp .env.example .env.local npm run dev ``` +如果遇到 `/_next/static/* 404` 或 `vendor-chunks` 缺失(Windows 上偶发的 Next 构建缓存污染),先清理再启动: +```bash +cd apps/web +npm run clean:next +npm run dev +``` + ### Docker 部署 ```bash diff --git a/Redis-x64-5.0.14.1/00-RELEASENOTES b/Redis-x64-5.0.14.1/00-RELEASENOTES new file mode 100644 index 0000000..21b4375 --- /dev/null +++ b/Redis-x64-5.0.14.1/00-RELEASENOTES @@ -0,0 +1,3630 @@ +Redis 5.0 release notes +======================= + +-------------------------------------------------------------------------------- +Upgrade urgency levels: + +LOW: No need to upgrade unless there are new features you want to use. +MODERATE: Program an upgrade of the server, but it's not urgent. +HIGH: There is a critical bug that may affect a subset of users. Upgrade! +CRITICAL: There is a critical bug affecting MOST USERS. Upgrade ASAP. +SECURITY: There are security fixes in the release. +-------------------------------------------------------------------------------- + +================================================================================ +Redis 5.0.14 Released Mon Oct 4 12:00:00 IDT 2021 +================================================================================ + +Upgrade urgency: SECURITY, contains fixes to security issues. + +Security Fixes: +* (CVE-2021-41099) Integer to heap buffer overflow handling certain string + commands and network payloads, when proto-max-bulk-len is manually configured + to a non-default, very large value [reported by yiyuaner]. +* (CVE-2021-32762) Integer to heap buffer overflow issue in redis-cli and + redis-sentinel parsing large multi-bulk replies on some older and less common + platforms [reported by Microsoft Vulnerability Research]. +* (CVE-2021-32687) Integer to heap buffer overflow with intsets, when + set-max-intset-entries is manually configured to a non-default, very large + value [reported by Pawel Wieczorkiewicz, AWS]. +* (CVE-2021-32675) Denial Of Service when processing RESP request payloads with + a large number of elements on many connections. +* (CVE-2021-32672) Random heap reading issue with Lua Debugger [reported by + Meir Shpilraien]. +* (CVE-2021-32628) Integer to heap buffer overflow handling ziplist-encoded + data types, when configuring a large, non-default value for + hash-max-ziplist-entries, hash-max-ziplist-value, zset-max-ziplist-entries + or zset-max-ziplist-value [reported by sundb]. +* (CVE-2021-32627) Integer to heap buffer overflow issue with streams, when + configuring a non-default, large value for proto-max-bulk-len and + client-query-buffer-limit [reported by sundb]. +* (CVE-2021-32626) Specially crafted Lua scripts may result with Heap buffer + overflow [reported by Meir Shpilraien]. + +================================================================================ +Redis 5.0.13 Released Wed Jul 21 16:32:19 IDT 2021 +================================================================================ + +Upgrade urgency: SECURITY, contains fixes to security issues that affect +authenticated client connections on 32-bit versions. MODERATE otherwise. + +Fix integer overflow in BITFIELD on 32-bit versions (CVE-2021-32761). +An integer overflow bug in Redis version 2.2 or newer can be exploited using the +BITFIELD command to corrupt the heap and potentially result with remote code +execution. + +Bug fixes: +* Fix overflows on 32-bit versions in GETBIT, SETBIT, BITCOUNT, BITPOS, and BITFIELD (#9191) +* Fix ziplist length updates on big-endian platforms (#2080) + +================================================================================ +Redis 5.0.12 Released Mon Mar 1 17:29:52 IST 2021 +================================================================================ + +Upgrade urgency: LOW, fixes a compilation issue. + +Bug fixes: +* Fix compilation error on non-glibc systems if jemalloc is not used (#8533) + +================================================================================ +Redis 5.0.11 Released Mon Feb 22 16:48:25 IST 2021 +================================================================================ + +Upgrade urgency: SECURITY if you use 32bit build of redis (see bellow), LOW +otherwise. + +Integer overflow on 32-bit systems (CVE-2021-21309): +Redis 4.0 or newer uses a configurable limit for the maximum supported bulk +input size. By default, it is 512MB which is a safe value for all platforms. +If the limit is significantly increased, receiving a large request from a client +may trigger several integer overflow scenarios, which would result with buffer +overflow and heap corruption. + +Bug fixes: +* Avoid 32-bit overflows when proto-max-bulk-len is set high (#8522) +* Fix an issue where a forked process deletes the parent's pidfile (#8231) +* Fix flock cluster config may cause failure to restart after kill -9 (#7674) +* Avoid an out-of-bounds read in the redis-sentinel (#7443) + +Platform and deployment-related changes: +* Fix setproctitle related crashes. (#8150, #8088) + Caused various crashes on startup, mainly on Apple M1 chips or under + instrumentation. +* Add a check for an ARM64 Linux kernel bug (#8224) + Due to the potential severity of this issue, Redis will refuse to run on + affected platforms by default. + +Modules: +* RM_ZsetRem: Delete key if empty, the bug could leave empty zset keys (#8453) + +================================================================================ +Redis 5.0.10 Released Mon Oct 26 09:21:49 IST 2020 +================================================================================ + +Upgrade urgency: SECURITY if you use an affected platform (see below). + Otherwise the upgrade urgency is MODERATE. + +This release fixes a potential heap overflow when using a heap allocator other +than jemalloc or glibc's malloc. See: +https://github.com/redis/redis/pull/7963 + +Other fixes in this release: + +* Avoid case of Lua scripts being consistently aborted due to OOM +* XPENDING will not update consumer's seen-time +* A blocked XREADGROUP didn't propagated the XSETID to replicas / AOF +* UNLINK support for streams +* RESTORE ABSTTL won't store expired keys into the DB +* Hide AUTH from MONITOR +* Cluster: reduce spurious PFAIL/FAIL states upon delayed PONG receival +* Cluster: Fix case of clusters mixing accidentally by gossip +* Cluster: Allow blocked XREAD on a cluster replica +* Cluster: Optimize memory usage CLUSTER SLOTS command +* RedisModule_ValueLength support for stream data type +* Minor fixes in redis-check-rdb and redis-cli +* Fix redis-check-rdb support for modules aux data +* Add fsync in replica when full RDB payload was received + +Full list of commits: + +Yossi Gottlieb in commit ce0d74d8f: + Fix wrong zmalloc_size() assumption. (#7963) + 1 file changed, 3 deletions(-) + +Yossi Gottlieb in commit 066699240: + Backport Lua 5.2.2 stack overflow fix. (#7733) + 1 file changed, 1 insertion(+), 1 deletion(-) + +WuYunlong in commit 8a90c7ef3: + Add fsync to readSyncBulkPayload(). (#7839) + 1 file changed, 11 insertions(+) + +Ariel Shtul in commit f0df2bb3c: + Fix redis-check-rdb support for modules aux data (#7826) + 3 files changed, 21 insertions(+), 1 deletion(-) + +hwware in commit 7add2a412: + fix memory leak in sentinel connection sharing + 1 file changed, 1 insertion(+) + +Oran Agra in commit 315e648f8: + Allow blocked XREAD on a cluster replica (#7881) + 3 files changed, 100 insertions(+), 2 deletions(-) + +guybe7 in commit 4967ee94e: + Modules: Invalidate saved_oparray after use (#7688) + 1 file changed, 2 insertions(+) + +antirez in commit 065003e8f: + Modules: remove spurious call from moduleHandleBlockedClients(). + 1 file changed, 1 deletion(-) + +Angus Pearson in commit 6cdf62928: + Fix broken interval and repeat bahaviour in redis-cli (incluing cluster mode) + 1 file changed, 11 insertions(+), 6 deletions(-) + +antirez in commit cb6a4971c: + Cluster: introduce data_received field. + 2 files changed, 27 insertions(+), 10 deletions(-) + +Madelyn Olson in commit 83f4de865: + Hide AUTH from monitor + 1 file changed, 1 insertion(+), 1 deletion(-) + +Guy Benoish in commit 3ba08d185: + Support streams in general module API functions + 3 files changed, 11 insertions(+), 1 deletion(-) + +Itamar Haber in commit 109c0635c: + Expands lazyfree's effort estimate to include Streams (#5794) + 1 file changed, 24 insertions(+) + +huangzhw in commit 235210d5b: + defrag.c activeDefragSdsListAndDict when defrag sdsele, We can't use (#7492) + 1 file changed, 1 insertion(+), 1 deletion(-) + +Oran Agra in commit fdd3162fe: + RESTORE ABSTTL skip expired keys - leak (#7511) + 1 file changed, 1 insertion(+) + +Oran Agra in commit 6139d6d18: + RESTORE ABSTTL won't store expired keys into the db (#7472) + 4 files changed, 45 insertions(+), 15 deletions(-) + +Liu Zhen in commit 0f502c58d: + fix clusters mixing accidentally by gossip + 1 file changed, 10 insertions(+), 2 deletions(-) + +Guy Benoish in commit 37fd50718: + XPENDING should not update consumer's seen-time + 4 files changed, 30 insertions(+), 18 deletions(-) + +antirez in commit a3ca53e4a: + Also use propagate() in streamPropagateGroupID(). + 1 file changed, 11 insertions(+), 1 deletion(-) + +yanhui13 in commit 7a62eb96e: + optimize the output of cluster slots + 1 file changed, 7 insertions(+), 4 deletions(-) + +srzhao in commit 0efb93d0c: + Check OOM at script start to get stable lua OOM state. + 3 files changed, 11 insertions(+), 4 deletions(-) + +================================================================================ +Redis 5.0.9 Released Thu Apr 17 12:41:00 CET 2020 +================================================================================ + +Upgrade urgency:CRITICAL if you use Streams with AOF ore replicas. + Otherwise the upgrade urgency is LOW. + +This release has a speed improvement and a critical fix: + + * FIX: XREADGROUP when fetching data in a blocking way, would not + emit the XCLAIM in the AOF file and to replicas. This means + that the last ID is not updated, and that restarting the server + will have the effect of reprocessing some entries. + * NEW: Clients blocked on the same key are now unblocked on + O(1) time. Backported from Redis 6. + +Commits: + + 1fc8ef81a Fix XCLAIM propagation in AOF/replicas for blocking XREADGROUP. + a5e24eabc Speedup: unblock clients on keys in O(1). + +================================================================================ +Redis 5.0.8 Released Thu Mar 12 16:05:41 CET 2020 +================================================================================ + +Upgrade urgency HIGH: This release fixes security issues. + +This is a list of fixes in this release: + +Salvatore Sanfilippo in commit 2bea502d: + Merge pull request #6975 from dustinmm80/add-arm-latomic-linking +Dustin Collins in commit b5931405: + Fix Pi building needing -latomic, backport + 1 file changed, 9 insertions(+) + +srzhao in commit fd441300: + fix impl of aof-child whitelist SIGUSR1 feature. + 1 file changed, 5 insertions(+), 4 deletions(-) + +Ariel in commit 77ff332b: + fix ThreadSafeContext lock/unlock function names + 1 file changed, 2 insertions(+), 2 deletions(-) + +Guy Benoish in commit 4f0f799c: + XREADGROUP should propagate XCALIM/SETID in MULTI/EXEC + 1 file changed, 2 insertions(+), 2 deletions(-) + +Oran Agra in commit 0c1273c3: + Fix client flags to be int64 in module.c + 1 file changed, 3 insertions(+), 3 deletions(-) + +Guy Benoish in commit 708a4e8a: + Fix small bugs related to replica and monitor ambiguity + 2 files changed, 8 insertions(+), 6 deletions(-) + +WuYunlong in commit eac4115d: + Fix lua related memory leak. + 1 file changed, 1 insertion(+) + +antirez in commit d075df17: + Simplify #6379 changes. + 2 files changed, 4 insertions(+), 9 deletions(-) + +WuYunlong in commit 80a49c37: + Free allocated sds in pfdebugCommand() to avoid memory leak. + 1 file changed, 1 insertion(+) + +antirez in commit 60870d3a: + Jump to right label on AOF parsing error. + 1 file changed, 6 insertions(+), 4 deletions(-) + +antirez in commit d90f599b: + Free fakeclient argv on AOF error. + 1 file changed, 11 insertions(+), 3 deletions(-) + +WuYunlong in commit 8ee3bddf: + Fix potential memory leak of rioWriteBulkStreamID(). + 1 file changed, 4 insertions(+), 1 deletion(-) + +WuYunlong in commit 4780fe78: + Fix potential memory leak of clusterLoadConfig(). + 1 file changed, 20 insertions(+), 5 deletions(-) + +Leo Murillo in commit f3b77510: + Fix bug on KEYS command where pattern starts with * followed by \x00 (null char). + 1 file changed, 1 insertion(+), 1 deletion(-) + +Guy Benoish in commit 7f3fcedb: + Blocking XREAD[GROUP] should always reply with valid data (or timeout) + 3 files changed, 44 insertions(+), 10 deletions(-) + +antirez in commit f93b2fa5: + XCLAIM: Create the consumer only on successful claims. + 1 file changed, 4 insertions(+), 2 deletions(-) + +Guy Benoish in commit 89682d96: + Stream: Handle streamID-related edge cases + 4 files changed, 54 insertions(+), 4 deletions(-) + +antirez in commit 920e108f: + Fix ip and missing mode in RM_GetClusterNodeInfo(). + 1 file changed, 5 insertions(+), 2 deletions(-) + +antirez in commit 7569b210: + Inline protocol: handle empty strings well. + 1 file changed, 2 insertions(+), 6 deletions(-) + +Khem Raj in commit 3c610b4e: + Mark extern definition of SDS_NOINIT in sds.h + 1 file changed, 1 insertion(+), 1 deletion(-) + +Seunghoon Woo in commit 16b2d07f: + [FIX] revisit CVE-2015-8080 vulnerability + 1 file changed, 6 insertions(+), 4 deletions(-) + +yz1509 in commit 19f33585: + avoid sentinel changes promoted_slave to be its own replica. + 1 file changed, 1 insertion(+), 1 deletion(-) + +================================================================================ +Redis 5.0.7 Released Tue Nov 19 17:52:44 CET 2019 +================================================================================ + +Upgrade urgency HIGH: many issues fixed, some may have an impact. + +Hi all, Redis 5.0.7 fixes a number of bugs, none is very critical, however +there are a few that may have an impact. It's a good idea to upgrade. +There are fixes in the area of replication from modules commands and +callbacks, AOF fsync (non critical issue), memory leaks (very rare and small), +streams beahvior (non critical), and a potential crash in commands +processing multiple keys at the same time that is there for years, and happens +very rarely, but is not impossible to trigger. + +The following is the list of commits in this release. + +antirez in commit 4d2a31ae: + Test: fix implementation-dependent test after code change. + 1 file changed, 2 insertions(+), 2 deletions(-) + +Oran Agra in commit 9f63fc98: + RED-31295 - redis: avoid race between dlopen and thread creation + 2 files changed, 17 insertions(+) + +antirez in commit 1a9e70c1: + Cluster: fix memory leak of cached master. + 2 files changed, 9 insertions(+), 4 deletions(-) + +Guy Benoish in commit 69b1b5be: + Fix usage of server.stream_node_max_* + 1 file changed, 3 insertions(+), 3 deletions(-) + +喜欢兰花山丘 in commit 1fd97ee7: + Update mkreleasehdr.sh + 1 file changed, 1 insertion(+), 1 deletion(-) + +antirez in commit 1a9855d7: + Remove additional space from comment. + 1 file changed, 1 insertion(+), 1 deletion(-) + +antirez in commit 32a6e3e4: + Fix stream test after addition of 0-0 ID test. + 1 file changed, 3 insertions(+), 3 deletions(-) + +Yuan Zhou in commit c9e6cda9: + aof: fix assignment for aof_fsync_offset + 1 file changed, 1 insertion(+), 1 deletion(-) + +antirez in commit d3eeacf9: + Merge branch '5.0' of github.com:/antirez/redis into 5.0 +antirez in commit da5dc458: + Rename var to fixed_time_expire now that is more general. + 4 files changed, 7 insertions(+), 8 deletions(-) + +antirez in commit 0fefed25: + Fix patch provided in #6554. + 1 file changed, 8 insertions(+), 1 deletion(-) + +zhaozhao.zz in commit e9fbc960: + expires & blocking: handle ready keys as call() + 1 file changed, 5 insertions(+) + +Guy Benoish in commit 08ec8f71: + XADD with ID 0-0 stores an empty key + 2 files changed, 14 insertions(+) + +Loris Cro in commit 09e1fe27: + fix unreported overflow in autogerenared stream IDs + 2 files changed, 19 insertions(+), 10 deletions(-) + +Salvatore Sanfilippo in commit 09f9e4b0: + Merge pull request #6600 from oranagra/5_module_flags +Oran Agra in commit 8d8d68dd: + module documentation mismatches: loading and fork child for 5.0 branch + 3 files changed, 11 insertions(+) + +antirez in commit 7a7fbe70: + Modules: RM_GetContextFlags(): remove non Redis 5 features. + 1 file changed, 3 deletions(-) + +antirez in commit b5830486: + Modules: fix moduleCreateArgvFromUserFormat() casting bug. + 1 file changed, 1 insertion(+), 1 deletion(-) + +antirez in commit b7a2a53a: + module: fix propagation API bug. + 1 file changed, 2 insertions(+), 2 deletions(-) + +antirez in commit 278bd6e3: + Modules: add new flags to context, replica state + more. + 2 files changed, 48 insertions(+), 1 deletion(-) + +antirez in commit 61d9a154: + Modules: RM_Call(): give pointer to documentation. + 1 file changed, 4 insertions(+), 1 deletion(-) + +antirez in commit 0e7ea0aa: + Modules: RM_Call/Replicate() ability to exclude AOF/replicas. + 1 file changed, 28 insertions(+), 9 deletions(-) + +antirez in commit 3b38164e: + Modules: RM_Replicate() in thread safe contexts. + 1 file changed, 26 insertions(+), 4 deletions(-) + +antirez in commit ef9fe9b0: + Modules: implement RM_Replicate() from async callbacks. + 2 files changed, 33 insertions(+), 2 deletions(-) + +antirez in commit 8066d2a1: + Modules: handle propagation when ctx is freed. Flag modules commands ctx. + 1 file changed, 23 insertions(+), 19 deletions(-) + +antirez in commit d3f4dec4: + Update PR #6537: use a fresh time outside call(). + 3 files changed, 27 insertions(+), 7 deletions(-) + +antirez in commit 33f42665: + Update PR #6537 patch to for generality. + 4 files changed, 40 insertions(+), 23 deletions(-) + +zhaozhao.zz in commit 68d71d83: + expires: refactoring judgment about whether a key is expired + 3 files changed, 3 insertions(+), 1 deletion(-) + +antirez in commit 62588dbf: + Modules: fix thread safe context creation crash. + 1 file changed, 1 insertion(+), 1 deletion(-) + +================================================================================ +Redis 5.0.6 Released Wed Sep 25 12:33:56 CEST 2019 +================================================================================ + +Upgrade urgency CRITICAL: Only in case of exposed instances to untrusted users. + +This Redis release, 5.0.6, is a bugfix and enhancement release. The most +important bugfix is a corruption related to the HyperLogLog. A malformed +HyperLogLog string could cause an invalid access to the memory. At a first +glance the vulnerability appears to be not exploitable but just a DoS. The +way to trigger the issue is complex, we'll not provide any information about +how to do that for the users safety. + +Other significant changes in this release: + +* New modules APIs merged from Redis unstable to Redis 5. +* Some memory optimization related to objects creation. +* Fixes to flushSlaveOutputBuffer() that make sure that SHUTDOWN will + transfer pending buffers to replicas. + +This is the full list of commits: + +antirez in commit 7a41047a: + RDB: fix MODULE_AUX loading by continuing to next opcode. + 1 file changed, 1 insertion(+) + +Oran Agra in commit 4eb3028b: + missing per-skiplist overheads in MEMORY USAGE + 1 file changed, 3 insertions(+), 1 deletion(-) + +Oran Agra in commit 5d09f9bc: + RM_Log - add support for logging without a context or context without module + 1 file changed, 6 insertions(+), 4 deletions(-) + +antirez in commit 2810de9f: + Cluster: abort loading nodes data if vars arguments are unbalanced. + 1 file changed, 1 insertion(+) + +antirez in commit f5c63ce0: + More strict checks and better comments in flushSlaveOutputBuffers(). + 1 file changed, 18 insertions(+), 7 deletions(-) + +antirez in commit 7f289c3b: + Improve comment in flushSlavesOutputBuffers(). + 1 file changed, 2 insertions(+), 1 deletion(-) + +antirez in commit 7ab62d4b: + Replication: clarify why repl_put_online_on_ack exists at all. + 2 files changed, 34 insertions(+), 10 deletions(-) + +zhaozhao.zz in commit 495dd0da: + networking: flushSlavesOutputBuffers bugfix + 1 file changed, 2 insertions(+), 4 deletions(-) + +Salvatore Sanfilippo in commit c1ccf0f1: + Merge pull request #6366 from oranagra/5.0_rm_reply_cstring +Salvatore Sanfilippo in commit a50dad73: + Merge pull request #6365 from oranagra/5.0_module_aux +Oran Agra in commit d6294d05: + RM_ReplyWithCString was missing registration + 1 file changed, 1 insertion(+) + +Oran Agra in commit 8c56fc86: + Fix to module aux data rdb format for backwards compatibility with old check-rdb + 1 file changed, 9 insertions(+), 1 deletion(-) + +Oran Agra in commit 98b1314f: + Implement module api for aux data in rdb + 9 files changed, 431 insertions(+), 18 deletions(-) + +antirez in commit 08b03e23: + redis-cli: always report server errors on read errors. + 1 file changed, 8 insertions(+), 1 deletion(-) + +wubostc in commit 239069de: + Reduce the calling stack + 1 file changed, 2 insertions(+), 3 deletions(-) + +antirez in commit 90bf6313: + Make EMBSTR case of #6261 more obvious. + 1 file changed, 1 insertion(+), 1 deletion(-) + +chendianqiang in commit 2f8a0749: + make memory usage consistent of robj with OBJ_ENCODING_INT + 1 file changed, 9 insertions(+), 4 deletions(-) + +antirez in commit 436ed56d: + HyperLogLog: fix the fix of a corruption bug. + 1 file changed, 1 insertion(+), 2 deletions(-) + +John Sully in commit 680f89fb: + Fix HLL corruption bug + 1 file changed, 1 insertion(+) + +swilly22 in commit 388efbf8: + Extend REDISMODULE_CTX_FLAGS to indicate if redis is currently loading from either RDB or AOF + 2 files changed, 5 insertions(+) + +Itamar Haber in commit 0ccbdcee: + Uses addReplyBulkCString + 1 file changed, 1 insertion(+), 1 deletion(-) + +Itamar Haber in commit 707a59c6: + Adds RedisModule_ReplyWithCString + 2 files changed, 13 insertions(+) + +================================================================================ +Redis 5.0.5 Released Wed May 15 17:57:41 CEST 2019 +================================================================================ + +Upgrade urgency CRITICAL: This release fixes an important AOF fysnc bug + and other less critical issues. + + +Dear user, + +Redis 5.0.5 fixes an important issue with AOF and adds multiple very useful +modules APIs. Moreover smaller bugs in other parts of Redis are fixed in +this release. + +The AOF bug +----------- + +The AOF bug happens when the fsync policy is set to "everysec", which is the +default: if the write load in the server drops immediately, the commands +executed in the latest second may not be fsync-ed to disk as it should. +This may lead to data loss in case the write load drops immediately and +successively a server crash happens. + +Other things in this release +---------------------------- + +* Streams: a bug in the iterator could prevent certain items to be returned in + range queries under specific conditions. +* Memleak in bitfieldCommand fixed. +* Modules API: Preserve client->id for blocked clients. +* Fix memory leak when rewriting config file in case of write errors. +* New modules API: RedisModule_GetKeyNameFromIO(). +* Fix non critical bugs in diskless replication. +* New mdouels API: command filtering. See RedisModule_RegisterCommandFilter(); +* Tests improved to be more deterministic. +* Fix a Redis Cluster bug, manual failover may abort because of the master + sending PINGs to the replicas. + +The following is the full list of commmits. + +Regards, +Salvatore + +Christian Zeller in commit 1cac9b4b: + Typo fixes in CONTRIBUTING + 1 file changed, 2 insertions(+), 2 deletions(-) + +antirez in commit f63c5c7b: + Update CONTRIBUTING with present info. + 1 file changed, 15 insertions(+), 5 deletions(-) + +antirez in commit 668661da: + Narrow the effects of PR #6029 to the exact state. + 1 file changed, 17 insertions(+), 5 deletions(-) + +chendianqiang in commit 3c2800e3: + stop ping when client pause + 1 file changed, 1 insertion(+), 1 deletion(-) + +antirez in commit 7ac7ffd5: + Test: fix slowlog test false positive. + 1 file changed, 3 insertions(+), 1 deletion(-) + +antirez in commit cc101721: + Make comment in getClientOutputBufferMemoryUsage() describing the present. + 1 file changed, 1 insertion(+), 8 deletions(-) + +WuYunlong in commit 72420b0d: + Do not active expire keys in the background when the switch is off. + 1 file changed, 6 insertions(+), 4 deletions(-) + +liaotonglang in commit 33a50d24: + delete sdsTest() from REDIS_TEST + 1 file changed, 2 deletions(-) + +zhaozhao.zz in commit 6a92836f: + test cases: skiptill -> skip-till + 1 file changed, 1 insertion(+), 1 deletion(-) + +Oran Agra in commit f179f71e: + make replication tests more stable on slow machines + 3 files changed, 34 insertions(+), 4 deletions(-) + +Yossi Gottlieb in commit 1825a4ec: + Add runtest-moduleapi with commandfilter coverage. + 5 files changed, 63 insertions(+), 28 deletions(-) + +Yossi Gottlieb in commit 9d20fdb4: + fix: missing initialization. + 3 files changed, 1 insertion(+) + +antirez in commit ded1980e: + Test: disable module testing for now. + 1 file changed, 1 deletion(-) + +Yossi Gottlieb in commit c3df78c2: + CommandFilter API: REDISMODULE_CMDFILTER_NOSELF. + 4 files changed, 62 insertions(+), 15 deletions(-) + +Yossi Gottlieb in commit 8d38ef20: + CommandFilter API: fix UnregisterCommandFilter. + 1 file changed, 2 insertions(+), 3 deletions(-) + +Yossi Gottlieb in commit 9b7009b1: + CommandFilter API: Add unregister option. + 4 files changed, 126 insertions(+), 32 deletions(-) + +Yossi Gottlieb in commit 05802442: + CommandFilter API: Extend documentation. + 1 file changed, 43 insertions(+), 5 deletions(-) + +Yossi Gottlieb in commit d5194daf: + CommandFilter API: hellofilter and tests. + 2 files changed, 47 insertions(+), 5 deletions(-) + +Yossi Gottlieb in commit 8897c154: + CommandFilter API: Support Lua and RM_call() flows. + 2 files changed, 18 insertions(+), 7 deletions(-) + +Yossi Gottlieb in commit 6dd5bad4: + CommandFilter API: More cleanup. + 2 files changed, 10 insertions(+), 29 deletions(-) + +Yossi Gottlieb in commit 83026101: + Add command filter Module API tests. + 2 files changed, 28 insertions(+) + +Yossi Gottlieb in commit dc5edc7b: + Add command filtering argument handling API. + 3 files changed, 132 insertions(+), 13 deletions(-) + +Yossi Gottlieb in commit 5f29e2e2: + Initial command filter experiment. + 6 files changed, 161 insertions(+), 2 deletions(-) + +Oran Agra in commit e1839ab3: + diskless fork kept streaming RDB to a disconnected slave + 1 file changed, 10 insertions(+) + +Oran Agra in commit 3b207b89: + diskless replication - notify slave when rdb transfer failed + 1 file changed, 1 insertion(+) + +antirez in commit 7e350b09: + More sensible name for function: restartAOFAfterSYNC(). + 1 file changed, 7 insertions(+), 3 deletions(-) + +antirez in commit 91238a60: + Mostly aesthetic changes to restartAOF(). + 1 file changed, 7 insertions(+), 3 deletions(-) + +oranagra in commit ee2da67c: + bugfix to restartAOF, exit will never happen since retry will get negative. + 1 file changed, 5 insertions(+), 4 deletions(-) + +Oran Agra in commit 78022492: + Add log when server dies of SIGTERM during loading + 1 file changed, 1 insertion(+) + +Yossi Gottlieb in commit 232dca7f: + Add RedisModule_GetKeyNameFromIO(). + 8 files changed, 30 insertions(+), 17 deletions(-) + +antirez in commit 7f98129a: + MANIFESTO: simplicity and lock-in. + 1 file changed, 5 insertions(+), 1 deletion(-) + +antirez in commit 71265fe3: + MANIFESTO v2. + 1 file changed, 41 insertions(+), 6 deletions(-) + +yongman in commit 8115be6e: + Fix uint64_t hash value in active defrag + 1 file changed, 3 insertions(+), 3 deletions(-) + +Angus Pearson in commit 90e7b5a9: + Enlarge error buffer in redis-check-aof.c to remove compiler warning of output truncation through snprintf format string + 1 file changed, 1 insertion(+), 1 deletion(-) + +zhaozhao.zz in commit 43151baf: + fix memory leak when rewrite config file + 1 file changed, 3 insertions(+), 4 deletions(-) + +唐权 in commit d3c17c9d: + Update ziplist.c + 1 file changed, 1 insertion(+), 1 deletion(-) + +stan011 in commit 296bd097: + change the comments there may have a mis type + 1 file changed, 1 insertion(+), 1 deletion(-) + +Yossi Gottlieb in commit e08c9c15: + Preserve client->id for blocked clients. + 1 file changed, 4 insertions(+), 1 deletion(-) + +zhaozhao.zz in commit c6b1252f: + aof: enhance AOF_FSYNC_EVERYSEC, more details in #5985 + 2 files changed, 32 insertions(+), 3 deletions(-) + +David Carlier in commit ce54e299: + build fix + 1 file changed, 1 insertion(+) + +yongman in commit c9274498: + Fix memleak in bitfieldCommand + 1 file changed, 8 insertions(+), 2 deletions(-) + +James Rouzier in commit 635d8d83: + Fix start and end key initialize + 1 file changed, 2 insertions(+), 2 deletions(-) + +Salvatore Sanfilippo in commit 7c23e534: + Merge pull request #6047 from abhaynahar/removed-obsolete-warning-5.0 +abhay in commit 9ea8ec42: + removed obsolete warning as per - https://github.com/antirez/redis/issues/5291 + 1 file changed, 1 insertion(+), 7 deletions(-) + +antirez in commit 1b7407fa: + Aesthetic change to #5962 to conform to Redis style. + 1 file changed, 1 insertion(+), 3 deletions(-) + +Oran Agra in commit 3bbf9747: + slave corrupts replication stream when module blocked client uses large reply (or POSTPONED_ARRAY) + 3 files changed, 15 insertions(+), 6 deletions(-) + +================================================================================ +Redis 5.0.4 Released Mon Mar 18 17:12:53 CET 2019 +================================================================================ + +Upgrade urgency HIGH: This release fixes several Redis stability issues. + +Dear Redis users, this release includes a number of fixes for bugs that may +result in Redis crashing in special conditions (not normal usage, but specific +artificial conditions), fixes to certain Redis behaviors especially around +Redis streams, and finally a set of new APIs for Redis Modules. + +Specifically: + +* Hyperloglog different coding errors leading to potential crashes were fixed. +* A replication bug leading to a potential crash in case of plain misuse of handshake commands was fixed. +* XCLAIM command incrementing of number of deliveries was fixed. +* LFU field management in objects was improved. +* A potential overflow in the redis-check-aof was fixed. +* A memory leak in case of API misuse was fixed. +* ZPOP* behavior when count is 0 is fixed. +* A few redis-cli --cluster bugs were fixed, plus a few improvements. +* Many other smaller bugs. + +We suggest to upgrade Redis, especially in case your instance is facing +untrusted users (for instance Cloud providers) because several of these +bugs could result in unwanted crashes. + +This is the list of commits: + +antirez in commit 84bdd440: + HyperLogLog: fix comment in hllCount(). + 1 file changed, 2 insertions(+), 2 deletions(-) + +antirez in commit ef1833b3: + HyperLogLog: handle wrong offset in the base case. + 1 file changed, 2 insertions(+), 6 deletions(-) + +antirez in commit 623afd5e: + HyperLogLog: speedup fuzz test. + 1 file changed, 1 insertion(+), 2 deletions(-) + +antirez in commit 12b5ff10: + HyperLogLog: enlarge reghisto variable for safety. + 1 file changed, 6 insertions(+), 1 deletion(-) + +antirez in commit 254d897e: + HyperLogLog: dense/sparse repr parsing fuzz test. + 1 file changed, 29 insertions(+) + +John Sully in commit 7f79849c: + Fix hyperloglog corruption + 1 file changed, 6 insertions(+) + +Brad Solomon in commit 3ef2c831: + Provide an uninstall target in Makefile + 1 file changed, 3 insertions(+) + +antirez in commit 57aea463: + redis-check-aof: fix potential overflow. + 1 file changed, 2 insertions(+), 2 deletions(-) + +antirez in commit ba5145b8: + Fix objectSetLRUOrLFU() when LFU underflows. + 1 file changed, 11 insertions(+), 7 deletions(-) + +antirez in commit 76c59f0e: + Fix ZPOP return type when COUNT=0. Related to #5799. + 1 file changed, 1 insertion(+), 1 deletion(-) + +antirez in commit 1c636714: + Improve comments after merging #5834. + 2 files changed, 14 insertions(+), 8 deletions(-) + +Guy Benoish in commit 6a3fca4c: + Trim SDS free space of retained module strings + 4 files changed, 28 insertions(+), 5 deletions(-) + +Guy Benoish in commit 9ec144ea: + Fix mismatching keyspace notification classes + 2 files changed, 2 insertions(+), 2 deletions(-) + +Guy Benoish in commit d04b5211: + Fix zlexrangespec mem-leak in genericZrangebylexCommand + 1 file changed, 4 insertions(+), 1 deletion(-) + +Guy Benoish in commit 516f1c77: + Use memtoll() in 'CONFIG SET client-output-buffer-limit' + 1 file changed, 2 insertions(+), 2 deletions(-) + +Guy Benoish in commit 8db67a55: + Increase string2ld's buffer size (and fix HINCRBYFLOAT) + 2 files changed, 5 insertions(+), 1 deletion(-) + +Guy Benoish in commit db3d626b: + Check server.verbosity in RM_LogRaw + 1 file changed, 2 insertions(+) + +Guy Benoish in commit 71439a07: + ZPOP should return an empty array if COUNT=0 + 1 file changed, 4 insertions(+), 1 deletion(-) + +antirez in commit c8a26834: + Modules shared API: export new core APIs. + 2 files changed, 6 insertions(+) + +antirez in commit a13ba750: + Modules shared API: also unregister the module as user. + 1 file changed, 23 insertions(+) + +antirez in commit 500e5117: + Modules shared API: prevent unloading of used modules. + 1 file changed, 10 insertions(+), 4 deletions(-) + +antirez in commit 7854daa1: + Modules shared API: unregister APIs function. + 1 file changed, 25 insertions(+) + +antirez in commit d38d82af: + Modules shared API: initial core functions. + 2 files changed, 89 insertions(+), 1 deletion(-) + +antirez in commit 4d747bb8: + Revert shared APIs to modify the design. + 3 files changed, 120 deletions(-) + +MeirShpilraien in commit 8824b509: + added module ability to register api to be used by other modules + 3 files changed, 120 insertions(+) + +zhaozhao.zz in commit 000b055b: + Streams: checkType before XGROUP CREATE + 1 file changed, 7 insertions(+), 5 deletions(-) + +antirez in commit 9b2a0d54: + Fix BZPOP arity, backport from fix in cd2743c. + 1 file changed, 2 insertions(+), 2 deletions(-) + +chendianqiang in commit 134b2582: + optimize cluster failover + 1 file changed, 1 insertion(+) + +Steve Webster in commit 1293e2a5: + Only increment delivery count if JUSTID option is omitted + 2 files changed, 18 insertions(+), 3 deletions(-) + +Steve Webster in commit 3cc4f469: + Increment delivery counter on XCLAIM unless RETRYCOUNT specified + 2 files changed, 35 insertions(+), 2 deletions(-) + +antirez in commit f4edd2b9: + Merge branch '5.0' of github.com:/antirez/redis into 5.0 +swilly22 in commit cedcc54e: + document additional flag of RM_GetContextFlags + 1 file changed, 3 insertions(+) + +swilly22 in commit 26e98da2: + Extend REDISMODULE_CTX_FLAGS to indicate if command was sent by master + 2 files changed, 6 insertions(+) + +Salvatore Sanfilippo in commit 0e910939: + Merge pull request #5879 from meierfra-ergon/redis-cli-assume-yes +antirez in commit 67452e91: + Make comment in #5911 stay inside 80 cols. + 1 file changed, 2 insertions(+), 1 deletion(-) + +John Sully in commit 30f666ef: + Replicas aren't allowed to run the replicaof command + 1 file changed, 8 insertions(+) + +Frank Meier in commit bc6c1c40: + extend use of cluster-yes option to other confimation questions + 1 file changed, 9 insertions(+) + +antirez in commit 76419d8d: + Merge branch '5.0' of github.com:/antirez/redis into 5.0 +Oran Agra in commit 72ba6069: + redis-cli add support for --memkeys, fix --bigkeys for module types + 1 file changed, 132 insertions(+), 81 deletions(-) + +chendianqiang in commit 2ca21753: + fix replicationid will not change for server.masterhost==NULL in cluster mode when restart slave + 1 file changed, 1 insertion(+), 1 deletion(-) + +Salvatore Sanfilippo in commit bd7ddd79: + Merge pull request #5870 from fengweiyuan/5.0 +varianfeng in commit d13bc143: + fix corrupt_rdb.c bug.Let the name of input rdb file name be valid. + 1 file changed, 2 insertions(+), 1 deletion(-) + +artix in commit 44c5bce0: + Cluster Manager: fix replica assigment anti-affinity (create) + 1 file changed, 6 insertions(+) + +artix in commit f066e526: + Cluster Manager: remove unused code elements + 1 file changed, 8 insertions(+), 13 deletions(-) + +Zhicheng Wei in commit 23214966: + fix clusterManagerGetAntiAffinityScore double free otypes + 1 file changed, 2 insertions(+), 1 deletion(-) + +antirez in commit 80bccd71: + Remove debugging printf from replication.tcl test. + 1 file changed, 1 deletion(-) + +================================================================================ +Redis 5.0.3 Released Tue Dec 11 18:17:26 CET 2018 +================================================================================ + +Upgrade urgency HIGH: Redis 5 is consolidating, upgrading is a good idea. + However there is nothing very critical here, but certain + issues resolved could lead to very rare crashes. + +Welcome to Redis 5.0.3, several interesting bug fixes here: + +* Redis no longer panics when you send data to a replica-mode connection that + is in MONITOR or SYNC mode. + +* Fixes to certain sorted set edge cases. You are unlikely to ever notice those + issues, but now it is more correct. + +* Certain BSD variants now are better supported: build & register logging + on crash. + +* The networking core now recovers if an IPv6 address is listed in bind but + is actually not able to work because there is no such protocol in the + system. + +* redis-cli cluster mode improved in many ways. Especially the fix subcommand + work was enhanced to cover other edge cases that were still not covered + after the work done for Redis 5. + +* MEMORY USAGE is now more accurate. + +* DEBUG DIGEST-VALUE added in case you want to make sure a given set of keys + (and not the whole DB) are excatly the same between two instances. + +* Fix a potential crash in the networking code related to recent changes + to the way the reply is consumed. + +* Reject EXEC containing write commands against an instance that changed role + from master to replica during our transaction. + +* Fix a crash in KEYS and other commands using pattern matching, in an edge + case where the pattern contains a zero byte. + +* Fix eviction during AOF loading due to maxmemory triggered by commands + executed in loading state. + +The following is the list of commmits if you want to check credits or dig +further in the details. + +commit 2c6ee0f9b3d9ca48c6da8bd18796186784216bff +Author: antirez +Date: Wed Dec 12 11:37:15 2018 +0100 + + freeMemoryIfNeeded() small refactoring. + + Related to issue #5686 and PR #5689. + +commit 107e93e75acfd5def0252efb6870751940816395 +Author: zhaozhao.zz +Date: Wed Dec 12 00:25:24 2018 +0800 + + evict: don't care about mem if loading + + When loading data, we call processEventsWhileBlocked + to process events and execute commands. + But if we are loading AOF it's dangerous, because + processCommand would call freeMemoryIfNeeded to evict, + and that will break data consistency, see issue #5686. + +antirez in commit ee93dc0b: + Crashing is too much in addReplyErrorLength(). + 1 file changed, 6 deletions(-) + +hdmg in commit c55254a5: + fix comments fault discription + 1 file changed, 1 insertion(+), 1 deletion(-) + +lsytj0413 in commit dfd25013: + fix a typo: craeted -> created + 1 file changed, 1 insertion(+), 1 deletion(-) + +antirez in commit 392a2566: + stringmatchlen() fuzz test added. + 3 files changed, 22 insertions(+) + +antirez in commit 7602f695: + Fix stringmatchlen() read past buffer bug. + 1 file changed, 1 insertion(+), 1 deletion(-) + +zhaozhao.zz in commit c4f3585e: + multi: ignore multiState's cmd_flags when loading AOF + 1 file changed, 1 insertion(+), 1 deletion(-) + +antirez in commit d037e987: + Reject EXEC containing write commands against RO replica. + 2 files changed, 20 insertions(+) + +artix in commit e00ab324: + Cluster Manager: - Multiple owners checking in 'fix'/'check' commands is + now optional (using --cluster-search-multiple-owners). - Updated help. + 1 file changed, 14 insertions(+), 5 deletions(-) + +artix in commit 94f64de3: + Cluster Manager: FixOpenSlot now correctly updates in-memory cluster + configuration. Improved output messages. + 1 file changed, 17 insertions(+), 5 deletions(-) + +artix in commit 752d636f: + Cluster Manager: 'fix' command now handles open slots with migrating state + in one node and importing state in multiple nodes. + 1 file changed, 74 insertions(+), 6 deletions(-) + +artix in commit 552091f9: + Cluster Manager: setting new slot owner is now handled atomically in + 'fix' command. + 1 file changed, 72 insertions(+), 31 deletions(-) + +artix in commit 2280f4f7: + Cluster Manager: code cleanup. + 1 file changed, 41 insertions(+), 87 deletions(-) + +artix in commit e084b8cc: + Cluster Manager: check/fix commands now handle multiple owners even + if all slots are covered and not open. + 1 file changed, 129 insertions(+), 6 deletions(-) + +zhaozhao.zz in commit fa726e2a: + remove useless tryObjectEncoding in debug assert + 1 file changed, 1 deletion(-) + +Oran Agra in commit 40244b10: + fix #5580, display fragmentation and rss overhead bytes as signed + 2 files changed, 6 insertions(+), 6 deletions(-) + +zhaozhao.zz in commit beab3151: + networking: current_client should not be NULL when trim qb_pos + 1 file changed, 1 insertion(+), 1 deletion(-) + +antirez in commit 07ccb642: + Remove no longer relevant comment in processCommand(). + 1 file changed, 2 insertions(+), 6 deletions(-) + +antirez in commit 60fdaf07: + DEBUG DIGEST-VALUE implemented. + 1 file changed, 17 insertions(+), 3 deletions(-) + +antirez in commit 48b31b0d: + DEBUG DIGEST refactoring: extract function to digest a value. + 1 file changed, 142 insertions(+), 131 deletions(-) + +yura in commit ef3ff402: + redis-cli reshard/rebalance: ability to force replacement on existing keys + 1 file changed, 6 insertions(+), 5 deletions(-) + +Thomas Orozco in commit ee223fb8: + cli: pass auth through REDISCLI_AUTH + 1 file changed, 14 insertions(+) + +yongman in commit 41295e55: + Fix cluster call reply format readable + 1 file changed, 1 insertion(+), 1 deletion(-) + +Oran Agra in commit 0ed3970f: + fix small test suite race conditions + 3 files changed, 11 insertions(+) + +zhaozhao.zz in commit 605dddbb: + MEMORY command: make USAGE more accurate + 1 file changed, 7 insertions(+), 6 deletions(-) + +yongman in commit 1f43bf29: + Fix choose a random master node for slot assignment + 1 file changed, 29 insertions(+), 5 deletions(-) + +Weiliang Li in commit 69f0c678: + fix comment typo in util.c + 1 file changed, 1 insertion(+), 1 deletion(-) + +Chris Lamb in commit bc53a3ab: + Clarify the "Creating Server TCP listening socket" error. + 1 file changed, 1 insertion(+), 1 deletion(-) + +Chris Lamb in commit fefe5460: + Don't treat unsupported protocols as fatal errors + 1 file changed, 4 insertions(+) + +David Carlier in commit a8862972: + OpenBSD support. + 3 files changed, 74 insertions(+), 1 deletion(-) + +David Carlier in commit 5e86daf9: + Backtrace/register dump on BSD. + 3 files changed, 97 insertions(+), 3 deletions(-) + +Guy Benoish in commit 7c8cf5ac: + Don't call sdscmp() with shared.maxstring or shared.minstring + 2 files changed, 23 insertions(+), 9 deletions(-) + +Qu Chen in commit 39e9eda3: + Add unit test for stream XCLAIM command. + 1 file changed, 48 insertions(+) + +antirez in commit 62485232: + Abort instead of crashing when loading bad stream master key. + 1 file changed, 3 insertions(+) + +Madelyn Olson in commit a5487309: + Fixed a serverPanic when sending an invalid command to a monitor client + 1 file changed, 1 insertion(+), 1 deletion(-) + +================================================================================ +Redis 5.0.2 Released Thu Nov 22 11:22:37 CET 2018 +================================================================================ + +Upgrade urgency: CRITICAL if you use streams and consumer groups. + HIGH if you use redis-cli with Redis Cluster. + LOW otherwise. + +Welcome to Redis 5.0.2. This release fixes two issues with Streams consumer +groups, where items could be returned duplicated by XREADGROUP when accessing +the history, and another bug where XREADGROUP can report some history even +if the comsumer pending list is empty. Both problems were addressed and unit +tests to avoid regressions implemented. Moreover this release fixes some +issue with redis-cli when in cluster mode. Finally some FreeBSD and DragonFly +build problems are now resolved. The list of the commits is below. + +Enjoy, +Salvatore + +David Carlier in commit e8b4291a: + DragonFlyBSD little build fix + 2 files changed, 6 insertions(+), 1 deletion(-) + +yongman in commit 8fcfd374: + skip slave nodes when sending cluster setslot command + 1 file changed, 1 insertion(+) + +yongman in commit d7089ddd: + Fix pointer access and memory leak in redis-cli. + 1 file changed, 6 insertions(+), 3 deletions(-) + +antirez in commit 17b4cd83: + Test: regression test for #5570. + 1 file changed, 15 insertions(+) + +antirez in commit 45123169: + Stream: fix XREADGROUP history reading of deleted messages. + 1 file changed, 1 insertion(+), 1 deletion(-) + +David Carlier in commit 5ad588f0: + only FreeBSD change/little warning addressing + 2 files changed, 7 insertions(+), 4 deletions(-) + +David Carlier in commit 11801e1a: + tweak form feedback + 1 file changed, 1 insertion(+), 1 deletion(-) + +David Carlier in commit c1f13575: + allow flavors + 1 file changed, 1 insertion(+), 1 deletion(-) + +David Carlier in commit 275a2d49: + Fix clang build. + 1 file changed, 5 insertions(+), 1 deletion(-) + +antirez in commit 44ad5141: + Test: regression test for #5577. + 1 file changed, 24 insertions(+) + +antirez in commit c7951f43: + Streams: fix XREADGROUP history reading when CG last_id is low. + 1 file changed, 12 insertions(+), 9 deletions(-) + +antirez in commit a69bc5be: + t_stream.c comment resized to 80 cols. + 1 file changed, 2 insertions(+), 1 deletion(-) + +antirez in commit 5314099d: + Redis 5 changelog: don't expect Lua replies to be ordered. + 1 file changed, 14 insertions(+), 5 deletions(-) + +================================================================================ +Redis 5.0.1 Released Wed Nov 07 13:09:30 CET 2018 +================================================================================ + +Upgrade urgency: URGENT if you use Redis Streams. MODERATE otherwise. + +Hi all, this is the first patch level release of Redis 5. It contains +both fixes and improvements. Here there is a list of the major ones, however +read the commit messages at the end of the changelog if you want to know +more about the smaller things. Let's start with the new features: + +* Sentinel now supports authentication! Check the Sentinel official doc + for more info. + +* Redis-cli cluster "fix" is now able to fix a big number of clusters put + in a bad condition. Previously many corner cases were not covered. + +Now the critical fixes: + +1. Fix RESTORE mismatch reply when certain keys already expired. +2. Fix an XCLAIM non trivial issue: sometimes the command returned a wrong + entry or desynchronized the protocol. + +And now the other fixes: + +3. Stack trace generation on the Raspberry PI (and 32bit ARM) fixed. +4. Don't evict expired keys when the KEYS command is called, in order to + avoid a mass deletion event. However expired keys are not displayed + by KEYS as usually. +5. Improvements in the computation of the memory used, when estimating + the AOF buffers. +6. XRANGE COUNT of 0 fixed. +7. "key misses" stats accounting fixed. Many cache misses were not counted. +8. When in MULTI state, return OOM while accumulating commands and there + is no longer memory available. +9. Fix build on FreeBSD and possibly others. +10. Fix a crash in Redis modules, thread safe context reply accumulation. +11. Fix a race condition when producing the RDB file for full SYNC. +12. Disable protected mode in Sentinel. +13. More commands now have the HELP subcommand. +14. Fixed an issue about adaptive server HZ timer. +15. Fix cluster-replica-no-failover option name. + +Finally, this is the list of commits. Enjoy Redis 5.0.1! + +antirez in commit c801283f: + Fix cluster-replica-no-failover option name. + 1 file changed, 1 insertion(+), 1 deletion(-) + +antirez in commit 4c4f50e1: + MEMORY command: make strcasecmp() conditional like the following. + 1 file changed, 1 insertion(+), 2 deletions(-) + +Itamar Haber in commit a7b46e0e: + Uppercases subcommands in MEMORY HELP + 1 file changed, 5 insertions(+), 5 deletions(-) + +Itamar Haber in commit 80e129d9: + Standardizes `MEMORY HELP` subcommand + 1 file changed, 13 insertions(+), 14 deletions(-) + +valentino in commit 88805cbb: + fix short period of server.hz being uninitialized + 1 file changed, 1 insertion(+), 1 deletion(-) + +Itamar Haber in commit 6b402733: + Adds HELP to LATENCY + 1 file changed, 14 insertions(+), 2 deletions(-) + +yongman in commit 1c637de9: + fix malloc in clusterManagerComputeReshardTable + 1 file changed, 1 insertion(+), 1 deletion(-) + +artix in commit 90b52fde: + Cluster Manager: removed unused var. + 1 file changed, 1 insertion(+), 2 deletions(-) + +artix in commit 89cbb5df: + Cluster Manager: further improvements to "fix": - clusterManagerFixOpenSlot: ensure that the slot is unassigned before ADDSLOTS - clusterManagerFixSlotsCoverage: after cold migration, the slot configuration is now updated on all the nodes. + 1 file changed, 49 insertions(+), 10 deletions(-) + +artix in commit 175515c9: + Cluster Manager: fixed string parsing issue in clusterManagerGetConfigSignature + 1 file changed, 3 insertions(+), 3 deletions(-) + +artix in commit 3997dd6e: + Cluster Manager: better fix subcommand. + 1 file changed, 78 insertions(+), 20 deletions(-) + +artix in commit bd80291c: + Cluster Manager: fixed typos in comments. + 1 file changed, 3 insertions(+), 3 deletions(-) + +artix in commit 4369cbce: + Cluster Manager: fixed 'DELSLOT' subcommand typo. + 1 file changed, 1 insertion(+), 1 deletion(-) + +antirez in commit 1ed821e2: + Fix XCLAIM missing entry bug. + 1 file changed, 3 insertions(+), 2 deletions(-) + +michael-grunder in commit b49bcd01: + Use typedef'd mstime_t instead of time_t + 1 file changed, 1 insertion(+), 1 deletion(-) + +antirez in commit 09d1849e: + Improve streamReplyWithRange() top comment. + 1 file changed, 9 insertions(+), 5 deletions(-) + +antirez in commit bdf6306f: + Add support for Sentinel authentication. + 1 file changed, 17 insertions(+), 3 deletions(-) + +antirez in commit 50222af5: + Disable protected mode in Sentinel mode. + 1 file changed, 1 insertion(+) + +antirez in commit 643ee6e3: + When replica kills a pending RDB save during SYNC, log it. + 1 file changed, 6 insertions(+) + +Andrey Bugaevskiy in commit 8b609c99: + Move child termination to readSyncBulkPayload + 1 file changed, 6 insertions(+), 7 deletions(-) + +Andrey Bugaevskiy in commit 27102605: + Prevent RDB autosave from overwriting full resync results + 1 file changed, 7 insertions(+) + +antirez in commit a677923d: + asyncCloseClientOnOutputBufferLimitReached(): don't free fake clients. + 1 file changed, 1 insertion(+) + +David Carlier in commit 427e440a: + needs it for the global + 1 file changed, 1 insertion(+) + +David Carlier in commit 28f9ca4e: + Fix non Linux build. + 3 files changed, 20 insertions(+), 1 deletion(-) + +zhaozhao.zz in commit 4bf9efe2: + MULTI: OOM err if cannot free enough memory in MULTI/EXEC context + 1 file changed, 5 insertions(+), 2 deletions(-) + +antirez in commit 4fbd7a39: + Add command fingerprint comment for XSETID. + 1 file changed, 3 insertions(+), 1 deletion(-) + +Itamar Haber in commit 2480db53: + Plugs a potential underflow + 1 file changed, 1 insertion(+) + +Itamar Haber in commit e5e4d2ef: + Corrects inline documentation of syntax + 1 file changed, 1 insertion(+), 1 deletion(-) + +zhaozhao.zz in commit 713800d2: + if we read a expired key, misses++ + 1 file changed, 5 insertions(+), 1 deletion(-) + +antirez in commit e79ee263: + Fix XRANGE COUNT option for value of 0. + 1 file changed, 8 insertions(+), 2 deletions(-) + +antirez in commit 505cc70f: + Fix typo in streamReplyWithRange() top comment. + 1 file changed, 1 insertion(+), 1 deletion(-) + +Damien Tournoud in commit 3c36561d: + Overhead is the allocated size of the AOF buffer, not its length + 2 files changed, 2 insertions(+), 2 deletions(-) + +antirez in commit 3761582f: + Simplify part of the #5470 patch. + 1 file changed, 11 insertions(+), 12 deletions(-) + +zhaozhao.zz in commit edc47a3a: + do not delete expired keys in KEYS command + 1 file changed, 34 insertions(+), 27 deletions(-) + +antirez in commit 9872af6d: + Use guide comments to make changes in #5462 more obvious. + 1 file changed, 6 insertions(+) + +youjiali1995 in commit 3f399c3b: + migrate: fix mismatch of RESTORE reply when some keys have expired. + 1 file changed, 8 insertions(+), 6 deletions(-) + +hujie in commit eaaff621: + fix typo in config.c + 1 file changed, 1 insertion(+), 1 deletion(-) + +hujiecs in commit 43ebb7ee: + several typos fixed, optimize MSETNX to avoid unnecessary loop + 4 files changed, 4 insertions(+), 4 deletions(-) + +antirez in commit de8fdaac: + Remove useless complexity from MSET implementation. + 1 file changed, 5 insertions(+), 7 deletions(-) + +antirez in commit dc8f1112: + Fix again stack generation on the Raspberry Pi. + 1 file changed, 4 insertions(+) + +antirez in commit 83a6e81d: + Get rid of the word slave in the release note of Redis 5. + 1 file changed, 2 insertions(+), 2 deletions(-) + +================================================================================ +Redis 5.0.0 Released Wed Oct 17 13:28:26 CEST 2018 +================================================================================ + +Upgrade urgency CRITICAL: Several fixes to streams AOF and replication. + +Hi all and welcome to the first stable release of Redis 5! \o/ + +To start a quick recap of what's new in Redis 5: + +1. The new Stream data type. https://redis.io/topics/streams-intro +2. New Redis modules APIs: Timers, Cluster and Dictionary APIs. +3. RDB now store LFU and LRU information. +4. The cluster manager was ported from Ruby (redis-trib.rb) to C code + inside redis-cli. Check `redis-cli --cluster help` for more info. +5. New sorted set commands: ZPOPMIN/MAX and blocking variants. +6. Active defragmentation version 2. +7. Improvemenets in HyperLogLog implementations. +8. Better memory reporting capabilities. +9. Many commands with sub-commands now have an HELP subcommand. +10. Better performances when clients connect and disconnect often. +11. Many bug fixes and other random improvements. +12. Jemalloc was upgraded to version 5.1 +13. CLIENT UNBLOCK and CLIENT ID. +14. The LOLWUT command was added. http://antirez.com/news/123 +15. We no longer use the "slave" word if not for API backward compatibility. +16. Differnet optimizations in the networking layer. +17. Lua improvements: + - Better propagation of Lua scripts to replicas / AOF. + - Lua scripts can now timeout and get in -BUSY state in the replica as well. +18. Dynamic HZ to balance idle CPU usage with responsiveness. +19. The Redis core was refactored and improved in many ways. + +However the list above really does not do justice to the changes of Redis 5 +since the core was improved in many ways during the development of the new +version. However certain changes were back ported into Redis 4 once they were +sensed as safe, because many improvements were hard to distinguish from fixes. + +The most important user facing improvement is without doubts the introduction +of the new general purpose data type after years: the streams. + +Note that we worked to improve and fix streams till a few hours ago, so while +we are not aware of critical bugs in this release, surely there is to handle it +with some care for the first weeks. Bug reporting will be highly appreciated and +we are ready to work immediately to release 5.0.1 once there is enough important +stuff to justify a new release (probably soon). + +People not using the streams can have probably a better production-ready +experience with Redis 5, also because many internals are shared with Redis 4 +so the jump is not as big as it was between 3.2 and 4 in terms of how things +internally work. + +Well, many thanks to the Redis community and the developers that made +this release possible, contributing bug reports, patches, new features, working +on the clients, sometimes debugging problems for days. Also thank to everybody +that adopted Redis for their use cases making things work for users worldwide. + +The list of commits in this release follows. + +Cheers, +Salvatore + +antirez in commit bcc0916d: + Fix conditional in XGROUP. + 1 file changed, 1 insertion(+), 1 deletion(-) + +antirez in commit 1b2f23f3: + Update help.h for redis-cli. + 1 file changed, 57 insertions(+), 7 deletions(-) + +antirez in commit de0ae56c: + Tests for XGROUP CREATE MKSTREAM. + 1 file changed, 11 insertions(+) + +antirez in commit 56c3dfa1: + Fix XGROUP CREATE MKSTREAM handling of . + 1 file changed, 7 insertions(+), 2 deletions(-) + +antirez in commit 2687f228: + Process MKSTREAM option of XGROUP CREATE at a later time. + 1 file changed, 28 insertions(+), 17 deletions(-) + +zhaozhao.zz in commit cfbaf8f1: + Scripting & Streams: some commands need right flags + 1 file changed, 5 insertions(+), 5 deletions(-) + +antirez in commit 4e4099b9: + XGROUP CREATE: MKSTREAM option for automatic stream creation. + 1 file changed, 29 insertions(+), 5 deletions(-) + +zhaozhao.zz in commit 6dd4d864: + Streams: Tests modified XSTREAM -> XSETID + 1 file changed, 2 insertions(+), 2 deletions(-) + +zhaozhao.zz in commit 3aff0e8c: + Streams: rewrite empty streams with certain lastid + 1 file changed, 1 insertion(+), 1 deletion(-) + +antirez in commit 880b563e: + Tests modified to use XADD MAXLEN 0 + XSETID. + 1 file changed, 12 insertions(+), 26 deletions(-) + +antirez in commit 83c87835: + Streams: rewrite empty streams with XADD MAXLEN 0. Use XSETID. + 1 file changed, 18 insertions(+), 12 deletions(-) + +antirez in commit fd22e3ac: + XSETID: accept IDs based on last entry. + 1 file changed, 18 insertions(+), 5 deletions(-) + +antirez in commit dfab3cba: + Streams: XSTREAM SETID -> XSETID. + 3 files changed, 17 insertions(+), 67 deletions(-) + +zhaozhao.zz in commit a3fb28ed: + Streams: rewrite id in XSTREAM CREATE * + 1 file changed, 4 insertions(+) + +zhaozhao.zz in commit f4b4db13: + Streams: add tests for aof rewrite + 1 file changed, 23 insertions(+) + +zhaozhao.zz in commit d22f1ef0: + Stream & AOF: rewrite stream in correct way + 1 file changed, 32 insertions(+), 16 deletions(-) + +zhaozhao.zz in commit 6455274d: + Streams: add tests for XSTREAM command + 1 file changed, 39 insertions(+) + +zhaozhao.zz in commit 0edbe953: + Streams: add a new command XTREAM + 3 files changed, 67 insertions(+) + +Hamid Alaei in commit 9714bba2: + fix timer context selected database + 1 file changed, 3 insertions(+), 1 deletion(-) + +antirez in commit eb53f15a: + Make comment about nack->consumer test for minidle more obvious. + 1 file changed, 4 insertions(+), 2 deletions(-) + +antirez in commit a77f836e: + Streams: use propagate_last_id itself as streamPropagateGroupID trigger. + 1 file changed, 2 insertions(+), 2 deletions(-) + +antirez in commit 0f0610eb: + Streams: better naming: lastid_updated -> propagate_last_id. + 1 file changed, 6 insertions(+), 6 deletions(-) + +zhaozhao.zz in commit a745e423: + Streams: panic if streamID invalid after check, should not be possible. + 1 file changed, 2 insertions(+), 1 deletion(-) + +zhaozhao.zz in commit 9974be13: + Streams: propagate lastid in XCLAIM when it has effect + 1 file changed, 13 insertions(+), 6 deletions(-) + +zhaozhao.zz in commit 69a628d0: + Streams: XCLAIM ignore minidle if NACK is created by FORCE + 1 file changed, 4 insertions(+), 2 deletions(-) + +zhaozhao.zz in commit a04b43c7: + Streams: bugfix XCLAIM should propagate group name not consumer name + 1 file changed, 1 insertion(+), 1 deletion(-) + +Sergey Chupov in commit 8977a90c: + fixed typos in readme + 1 file changed, 2 insertions(+), 2 deletions(-) + +antirez in commit 3a745674: + redis.conf typo fixed: ingore -> ignore. + 1 file changed, 1 insertion(+), 1 deletion(-) + +antirez in commit 22770d76: + Rax: radix tree updated to latest version from antirez/rax. + 2 files changed, 233 insertions(+), 68 deletions(-) + +antirez in commit fbac534f: + Test: avoid time related false positive in RESTORE test. + 1 file changed, 1 insertion(+), 1 deletion(-) + +antirez in commit 49872337: + LOLWUT: capitalize Nees. + 1 file changed, 1 insertion(+), 1 deletion(-) + +antirez in commit 80c471f5: + Test: cgroup propagation test also for NOACK variant. + 1 file changed, 39 insertions(+), 29 deletions(-) + +antirez in commit 8defa5da: + Test: consumer group last ID slave propagation test. + 1 file changed, 39 insertions(+) + +zhaozhao.zz in commit e1e3eaca: + Avoid recreate write handler for protected client. + 1 file changed, 4 insertions(+) + +antirez in commit b501fd5d: + Fix propagation of consumer groups last ID. + 3 files changed, 56 insertions(+), 9 deletions(-) + + +================================================================================ +Redis 5.0-rc6 Released Wed Oct 10 11:03:54 CEST 2018 +================================================================================ + +Upgrade urgency HIGH: Many bugs fixed especially in the context of streams. + +This is probably the last release candidate of Redis 5. The Redis 5 GA version +will be released 17th of October. The main highlights of this release are: + +* Critical AOF bug, as old as AOF itself: if an open MULTI/EXEC block is at + the end of the AOF file, Redis would still read the half-transaction when + reloading back the AOF. +* The slave name was removed from logs and documentation, now replica is used + instead. +* LOLWUT command added. +* New modules APIs: Disable Redis Cluster redirection. +* New modules APIs: Sorted dictionaries data type. +* Modules APIs fixes: timer / cluster messages callback now can call RM_Call(). +* Fix for #5024 - commandstats for multi-exec were logged as EXEC. +* A number of optimizations and fixes for the stream data type. +* Many other stability improvements. + +This is the list of comments and contributors: + +antirez in commit 9a6fa7d0: + changelog.tcl: get optional argument for number of commits. + 1 file changed, 8 insertions(+), 3 deletions(-) + +antirez in commit 101e419f: + Free protected clients asynchronously. + 1 file changed, 7 insertions(+) + +antirez in commit 726debb8: + Actually use the protectClient() API where needed. + 2 files changed, 8 insertions(+), 9 deletions(-) + +antirez in commit 0b87f78a: + Introduce protectClient() + some refactoring. + 2 files changed, 60 insertions(+), 18 deletions(-) + +zhaozhao.zz in commit 6aa8ac70: + debug: avoid free client unexpectedly when reload & loadaof + 1 file changed, 8 insertions(+), 2 deletions(-) + +antirez in commit 48040b02: + aof.c: improve indentation and change warning message. + 1 file changed, 11 insertions(+), 4 deletions(-) + +zhaozhao.zz in commit 7cc20569: + AOF: discard if we lost EXEC when loading aof + 2 files changed, 14 insertions(+), 3 deletions(-) + +antirez in commit 2007d30c: + Refactoring of XADD / XTRIM MAXLEN rewriting. + 1 file changed, 15 insertions(+), 22 deletions(-) + +zhaozhao.zz in commit 6a298110: + Streams: add test cases for XADD/XTRIM maxlen + 1 file changed, 46 insertions(+) + +zhaozhao.zz in commit 041161b7: + Streams: propagate specified MAXLEN instead of approximated + 1 file changed, 35 insertions(+), 6 deletions(-) + +zhaozhao.zz in commit f04d799b: + Streams: reset approx_maxlen in every maxlen loop + 1 file changed, 2 insertions(+) + +zhaozhao.zz in commit affd9365: + Streams: XTRIM will return an error if MAXLEN with a count < 0 + 1 file changed, 6 insertions(+), 1 deletion(-) + +zhaozhao.zz in commit 4c405ad0: + Streams: propagate original MAXLEN argument in XADD context + 1 file changed, 3 insertions(+), 12 deletions(-) + +antirez in commit 5c6d4b4a: + Fix typo in replicationCron() comment. + 1 file changed, 1 insertion(+), 1 deletion(-) + +antirez in commit a67a8dbf: + Fix typo in design comment of bio.c. + 1 file changed, 1 insertion(+), 1 deletion(-) + +antirez in commit c4ab5a05: + xclaimCommand(): fix comment typos. + 1 file changed, 2 insertions(+), 2 deletions(-) + +antirez in commit dc0b628a: + streamAppendItem(): Update the radix tree pointer only if changed. + 1 file changed, 2 insertions(+), 1 deletion(-) + +antirez in commit 4566fbc7: + Listpack: optionally force reallocation on inserts. + 1 file changed, 20 insertions(+) + +antirez in commit 5eca170c: + Fix printf type mismatch in genRedisInfoString(). + 1 file changed, 1 insertion(+), 1 deletion(-) + +antirez in commit 260b53a2: + streamIteratorRemoveEntry(): set back lp only if pointer changed. + 1 file changed, 2 insertions(+), 1 deletion(-) + +zhaozhao.zz in commit 5d12f9d9: + Streams: update listpack with new pointer in XDEL + 1 file changed, 3 insertions(+) + +zhaozhao.zz in commit 6b7ad838: + bugfix: replace lastcmd with cmd when rewrite BRPOPLPUSH as RPOPLPUSH + 1 file changed, 1 insertion(+), 1 deletion(-) + +Oran Agra in commit 3454a043: + script cache memory in INFO and MEMORY includes both script code and overheads + 2 files changed, 3 insertions(+), 3 deletions(-) + +Oran Agra in commit d6aeca86: + fix #5024 - commandstats for multi-exec were logged as EXEC. + 2 files changed, 63 insertions(+), 2 deletions(-) + +antirez in commit a996b2a2: + Fix XINFO comment for consistency. + 1 file changed, 1 insertion(+), 1 deletion(-) + +Bruce Merry in commit 1a8447b6: + Fix invalid use of sdsZmallocSize on an embedded string + 1 file changed, 1 insertion(+), 1 deletion(-) + +Bruce Merry in commit 8dde46ad: + Fix incorrect memory usage accounting in zrealloc + 3 files changed, 24 insertions(+), 2 deletions(-) + +Hamid Alaei in commit b362a1b7: + fix dict get on not found + 1 file changed, 1 insertion(+), 1 deletion(-) + +antirez in commit 55e9df8a: + Try to avoid issues with GCC pragmas and older compilers. + 1 file changed, 7 insertions(+), 4 deletions(-) + +antirez in commit b0d22702: + Modules: hellodict example WIP #3: KEYRANGE. + 1 file changed, 40 insertions(+) + +antirez in commit af2f6682: + Modules: Modules: dictionary API WIP #13: Compare API exported. + 2 files changed, 6 insertions(+) + +antirez in commit f9a3e6ef: + Modules: Modules: dictionary API WIP #12: DictCompare API. + 1 file changed, 8 insertions(+) + +antirez in commit 01e0341a: + Modules: Modules: dictionary API WIP #11: DictCompareC API. + 1 file changed, 18 insertions(+) + +antirez in commit f9b3ce9a: + Modules: hellodict example WIP #1: GET command. + 1 file changed, 18 insertions(+) + +antirez in commit 36e66d86: + Modules: hellodict example WIP #1: SET command. + 1 file changed, 74 insertions(+) + +antirez in commit e33fdbe8: + Modules: remove useless defines in hellotimer.c + 2 files changed, 6 insertions(+), 4 deletions(-) + +antirez in commit 1c8b2248: + Modules: fix top comment of hellotimer.c + 1 file changed, 1 insertion(+), 1 deletion(-) + +Guy Korland in commit 7ded552d: + add missing argument to function doc + 1 file changed, 1 insertion(+), 1 deletion(-) + +Pavel Skuratovich in commit f92b3273: + Fix typo in comment + 1 file changed, 1 insertion(+), 1 deletion(-) + +antirez in commit 57b6c343: + Modules: dictionary API WIP #10: export API to modules. + 2 files changed, 60 insertions(+) + +antirez in commit 3f82e59c: + Modules: dictionary API WIP #9: iterator returning string object. + 1 file changed, 23 insertions(+), 6 deletions(-) + +antirez in commit 6a73aca3: + Modules: dictionary API WIP #8: Iterator next/prev. + 1 file changed, 42 insertions(+) + +antirez in commit ef8413db: + Modules: dictionary API WIP #7: don't store the context. + 1 file changed, 7 insertions(+), 8 deletions(-) + +antirez in commit 05579e38: + Modules: dictionary API WIP #6: implement automatic memory management. + 1 file changed, 21 insertions(+), 7 deletions(-) + +antirez in commit 11c53f8c: + Modules: dictionary API work in progress #5: rename API for consistency. + 1 file changed, 25 insertions(+), 25 deletions(-) + +antirez in commit 0bd7091b: + Modules: change RedisModuleString API to allow NULL context. + 1 file changed, 33 insertions(+), 12 deletions(-) + +antirez in commit 5fc16f17: + Modules: dictionary API work in progress #4: reseek API. + 1 file changed, 25 insertions(+), 6 deletions(-) + +antirez in commit 45b7f779: + Modules: dictionary API work in progress #3: Iterator creation. + 1 file changed, 41 insertions(+), 1 deletion(-) + +antirez in commit 8576b0ae: + Modules: dictionary API work in progress #2: Del API. + 1 file changed, 17 insertions(+), 2 deletions(-) + +antirez in commit 4b0fa7a7: + Modules: dictionary API work in progress #1. + 2 files changed, 95 insertions(+), 1 deletion(-) + +antirez in commit 28210760: + Module cluster flags: use RM_SetClusterFlags() in the example. + 2 files changed, 11 insertions(+) + +antirez in commit 18c5ab93: + Module cluster flags: add RM_SetClusterFlags() API. + 3 files changed, 33 insertions(+) + +antirez in commit 4ce6bff2: + Module cluster flags: add hooks for NO_FAILOVER flag. + 1 file changed, 4 insertions(+), 2 deletions(-) + +antirez in commit 2ba52889: + Module cluster flags: add hooks for NO_REDIRECTION flag. + 3 files changed, 14 insertions(+), 4 deletions(-) + +antirez in commit 6a39ece6: + Module cluster flags: initial vars / defines added. + 5 files changed, 20 insertions(+) + +antirez in commit 0ff35370: + Modules: rename the reused static client to something more general. + 1 file changed, 10 insertions(+), 8 deletions(-) + +antirez in commit 2d11ee95: + Modules: associate a fake client to timer context callback. + 1 file changed, 2 insertions(+) + +antirez in commit 851b2ed3: + Modules: associate a fake client to cluster message context callback. + 1 file changed, 2 insertions(+) + +artix in commit 148e4911: + Cluster Manager: clusterManagerFixOpenSlot now counts node's keys in slot if node is neither migrating nor importing. + 1 file changed, 20 insertions(+), 1 deletion(-) + +Guy Korland in commit 8afca145: + No need to return "OK" + 1 file changed, 1 insertion(+), 1 deletion(-) + +Guy Korland in commit 9a278db2: + typo fix + 1 file changed, 1 insertion(+), 1 deletion(-) + +antirez in commit 26479036: + Revert "fix repeat argument issue and reduce unnessary loop times for redis-cli." + 1 file changed, 7 insertions(+), 12 deletions(-) + +Guy Korland in commit 27b7fb5a: + Fix few typos + 1 file changed, 10 insertions(+), 10 deletions(-) + +Guy Korland in commit 233aa2d3: + RedisModule_HashSet call must end with NULL + 1 file changed, 3 insertions(+), 1 deletion(-) + +antirez in commit a8494072: + Sentinel: document how to undo a renamed command. + 1 file changed, 6 insertions(+), 1 deletion(-) + +antirez in commit 6c8a8f2e: + LOLWUT: split the command from version-specific implementations. + 3 files changed, 297 insertions(+), 241 deletions(-) + +antirez in commit 5c758406: + Slave removal: add a few forgotten aliases for CONFIG SET. + 1 file changed, 10 insertions(+) + +antirez in commit 2da823c4: + LOLWUT: add Redis version in the output. + 1 file changed, 3 insertions(+), 1 deletion(-) + +antirez in commit bfcba420: + LOLWUT: Ness -> Nees. + 1 file changed, 1 insertion(+), 1 deletion(-) + +antirez in commit efed898a: + LOLWUT: Limit maximum CPU effort. + 1 file changed, 5 insertions(+) + +antirez in commit eb0fbd71: + LOLWUT: change padding conditional to a more direct one. + 1 file changed, 1 insertion(+), 1 deletion(-) + +Slobodan Mišković in commit ed08feb7: + Fix spelling descrive -> describe + 1 file changed, 1 insertion(+), 1 deletion(-) + +antirez in commit 2ffb4413: + LOLWUT: fix crash when col < 2. + 1 file changed, 1 insertion(+), 1 deletion(-) + +antirez in commit 55dae693: + LOLWUT: fix structure typo in comment. + 1 file changed, 1 insertion(+), 1 deletion(-) + +antirez in commit 9b3098b9: + LOLWUT: Fix license copyright year. + 1 file changed, 1 insertion(+), 1 deletion(-) + +antirez in commit 263dbadc: + LOLWUT: increase the translation factor. + 1 file changed, 2 insertions(+), 2 deletions(-) + +antirez in commit a622f6c0: + LOLWUT: change default size to fit a normal terminal better. + 1 file changed, 6 insertions(+), 6 deletions(-) + +antirez in commit 38b0d25a: + LOLWUT: wrap it into a proper command. + 4 files changed, 40 insertions(+), 15 deletions(-) + +antirez in commit 34ebd898: + LOLWUT: draw Schotter by Georg Nees. + 1 file changed, 47 insertions(+), 3 deletions(-) + +antirez in commit 46286e64: + LOLWUT: draw rotated squares using trivial trigonometry. + 1 file changed, 44 insertions(+) + +antirez in commit 2d4143fd: + LOLWUT: draw lines using Bresenham algorithm. + 1 file changed, 26 insertions(+), 2 deletions(-) + +antirez in commit 3546d9ce: + LOLWUT: Rendering of the virtual canvas to a string. + 1 file changed, 78 insertions(+), 7 deletions(-) + +antirez in commit b404a6ce: + LOLWUT: show the output verbatim in redis-cli. + 1 file changed, 1 insertion(+) + +antirez in commit e30ba94f: + LOLWUT: canvas structure and BSD license on top. + 1 file changed, 46 insertions(+) + +antirez in commit 9c771145: + LOLWUT: Emit Braille unicode according to pixel pattern. + 1 file changed, 23 insertions(+) + +Jakub Vrana in commit 4a1d6c7d: + Slave removal: capitalize Replica + 2 files changed, 5 insertions(+), 5 deletions(-) + +antirez in commit 72e0368a: + Slave removal: remove slave from integration tests descriptions. + 8 files changed, 36 insertions(+), 36 deletions(-) + +antirez in commit c7841c2b: + Slave removal: remove slave from top-level tests descriptions. + 3 files changed, 12 insertions(+), 12 deletions(-) + +antirez in commit 1b9b19ba: + Slave removal: remove slave from object.c. + 1 file changed, 1 insertion(+), 1 deletion(-) + +antirez in commit 7da266e6: + Slave removal: remove slave from the README. + 1 file changed, 7 insertions(+), 7 deletions(-) + +antirez in commit 93d803c9: + Slave removal: server.c logs fixed. + 1 file changed, 5 insertions(+), 5 deletions(-) + +antirez in commit 89434032: + Slave removal: remove slave from sentinel.conf when possible. + 1 file changed, 18 insertions(+), 18 deletions(-) + +antirez in commit 7673d88d: + Slave removal: replace very few things in Sentinel. + 1 file changed, 12 insertions(+), 8 deletions(-) + +antirez in commit f1de29b3: + Slave removal: scripting.c logs and other stuff fixed. + 1 file changed, 6 insertions(+), 2 deletions(-) + +antirez in commit 53fe558e: + Slave removal: replication.c logs fixed. + 1 file changed, 35 insertions(+), 35 deletions(-) + +antirez in commit c92b02dd: + Slave removal: networking.c logs fixed. + 1 file changed, 5 insertions(+), 5 deletions(-) + +antirez in commit be76ed0c: + Slave removal: blocked.c logs fixed. + 1 file changed, 1 insertion(+), 1 deletion(-) + +antirez in commit 3fd73151: + Slave removal: Make obvious in redis.conf what a replica is. + 1 file changed, 5 insertions(+) + +antirez in commit a22168e4: + Slave removal: slave mode -> replica mode text in redis-cli. + 1 file changed, 1 insertion(+), 1 deletion(-) + +antirez in commit 0e222fbe: + Slave removal: fix typo of replicaof. + 1 file changed, 1 insertion(+), 1 deletion(-) + +antirez in commit 34a5615e: + Slave removal: slave -> replica in redis.conf and output buffer option. + 3 files changed, 132 insertions(+), 129 deletions(-) + +antirez in commit 1d2fcf6f: + Slave removal: Convert cluster.c log messages and command names. + 1 file changed, 12 insertions(+), 11 deletions(-) + +antirez in commit 2546158d: + Slave removal: config.c converted + config rewriting hacks. + 1 file changed, 117 insertions(+), 38 deletions(-) + +antirez in commit c0952c0d: + Slave removal: redis-cli --slave -> --replica. + 1 file changed, 3 insertions(+), 1 deletion(-) + +antirez in commit 1f37f1dd: + Slave removal: SLAVEOF -> REPLICAOF. SLAVEOF is now an alias. + 3 files changed, 4 insertions(+), 3 deletions(-) + +Amin Mesbah in commit 7928f578: + Use geohash limit defines in constraint check + 1 file changed, 2 insertions(+), 2 deletions(-) + +Jeffrey Lovitz in commit bb2bed78: + CLI Help text loop verifies arg count + 1 file changed, 1 insertion(+), 1 deletion(-) + +youjiali1995 in commit 246980d0: + sentinel: fix randomized sentinelTimer. + 1 file changed, 1 insertion(+), 3 deletions(-) + +youjiali1995 in commit fa7de8c4: + bio: fix bioWaitStepOfType. + 1 file changed, 3 insertions(+), 3 deletions(-) + +Weiliang Li in commit 7642f9d5: + fix usage typo in redis-cli + 1 file changed, 1 insertion(+), 1 deletion(-) + +================================================================================ +Redis 5.0 RC5 Released Thu Sep 06 12:54:29 CEST 2018 +================================================================================ + +Upgrade urgency HIGH: Several imporant bugs fixed. + +Hi all, + +This is the release candidate number five, and has a lot of bug fixes inside, +together with a few big changes to the Redis behavior from the point of view +of replication of scripts and handling of the maxmemory directive in slaves. +Make sure to read the whole list! + +* BREAKING BEHAVIOR: Slaves now ignore maxmemory by default. +* BREAKING BEHAVIOR: Now scripts are always replicated for their effects, and + never sending the script itself to slaves/AOF. +* Improvement: Big pipelining performances improved significantly. +* Fix: Rewrite BRPOPLPUSH as RPOPLPUSH to propagate. +* Fix: False positives in tests. +* Fix: Certain command flags were modified because not correct. +* Fix: Fix blocking XREAD for streams that are empty. +* Improvement: Allow scripts to timeout on slaves as well. +* Fix: Different corner cases due to CLIENT PAUSE are now fixed. +* Improvement: Optimize parsing large bulk greater than 32k. +* Fix: Propagate read-only scripts as SCRIPT LOAD, not as EVAL. + +The following is the list of commits, so that you can read the details and +check the credits of the commits. + +antirez in commit 1d1bf7f0: + Document that effects replication is Redis 5 default. + 1 file changed, 8 insertions(+) + +antirez in commit cfd969c7: + Fix scripting tests now that we default to commands repl. + 1 file changed, 8 insertions(+), 1 deletion(-) + +antirez in commit 3e1fb5ff: + Use commands (effects) replication by default in scripts. + 3 files changed, 8 insertions(+), 1 deletion(-) + +antirez in commit c6c71abe: + Safer script stop condition on OOM. + 1 file changed, 5 insertions(+), 2 deletions(-) + +antirez in commit dfbce91a: + Propagate read-only scripts as SCRIPT LOAD. + 1 file changed, 16 insertions(+), 3 deletions(-) + +antirez in commit 1705e42e: + Don't perform eviction when re-entering the event loop. + 1 file changed, 7 insertions(+), 2 deletions(-) + +antirez in commit a0dd6f82: + Clarify why remaining may be zero in readQueryFromClient(). + 1 file changed, 2 insertions(+) + +zhaozhao.zz in commit 2eed31a5: + networking: fix unexpected negative or zero readlen + 1 file changed, 1 insertion(+), 1 deletion(-) + +antirez in commit 37fb606c: + Merge branch '5.0' of github.com:/antirez/redis into 5.0 +zhaozhao.zz in commit 1898e6ce: + networking: optimize parsing large bulk greater than 32k + 1 file changed, 13 insertions(+), 10 deletions(-) + +antirez in commit 82fc63d1: + Unblocked clients API refactoring. See #4418. + 4 files changed, 33 insertions(+), 15 deletions(-) + +zhaozhao.zz in commit 839bb52c: + if master is already unblocked, do not unblock it twice + 1 file changed, 1 insertion(+), 1 deletion(-) + +zhaozhao.zz in commit 2e1cd82d: + fix multiple unblock for clientsArePaused() + 1 file changed, 3 insertions(+), 3 deletions(-) + +antirez in commit 17233080: + Make pending buffer processing safe for CLIENT_MASTER client. + 3 files changed, 22 insertions(+), 13 deletions(-) + +antirez in commit 42bce87a: + Test: processing of master stream in slave -BUSY state. + 1 file changed, 44 insertions(+) + +antirez in commit 8bf42f60: + After slave Lua script leaves busy state, re-process the master buffer. + 2 files changed, 5 insertions(+), 2 deletions(-) + +antirez in commit c2b104c7: + While the slave is busy, just accumulate master input. + 2 files changed, 6 insertions(+), 1 deletion(-) + +antirez in commit 7b75f4ae: + Allow scripts to timeout even if from the master instance. + 1 file changed, 6 insertions(+), 11 deletions(-) + +antirez in commit adc4e031: + Allow scripts to timeout on slaves as well. + 2 files changed, 10 insertions(+), 3 deletions(-) + +dejun.xdj in commit 20ec1f0c: + Revise the comments of latency command. + 1 file changed, 2 insertions(+), 1 deletion(-) + +Chris Lamb in commit 8e5423eb: + Correct "did not received" -> "did not receive" typos/grammar. + 6 files changed, 10 insertions(+), 10 deletions(-) + +zhaozhao.zz in commit 395063d7: + remove duplicate bind in sentinel.conf + 1 file changed, 10 deletions(-) + +Salvatore Sanfilippo in commit b221ca41: + Merge pull request #5300 from SaschaRoland/xread-block-5299 +Sascha Roland in commit eea0d3c5: + #5299 Fix blocking XREAD for streams that ran dry + 1 file changed, 2 insertions(+), 2 deletions(-) + +antirez in commit 4cb9ee11: + Add maxmemory slave behavior change in the change log. + 1 file changed, 8 insertions(+) + +zhaozhao.zz in commit 5ad888ba: + Supplement to PR #4835, just take info/memory/command as random commands + 1 file changed, 3 insertions(+), 3 deletions(-) + +zhaozhao.zz in commit d928487f: + some commands' flags should be set correctly, issue #4834 + 1 file changed, 14 insertions(+), 14 deletions(-) + +Oran Agra in commit af675f0a: + Fix unstable tests on slow machines. + 3 files changed, 23 insertions(+), 17 deletions(-) + +antirez in commit f2cd16be: + Document slave-ignore-maxmemory in redis.conf. + 1 file changed, 20 insertions(+) + +antirez in commit 02d729b4: + Make slave-ignore-maxmemory configurable. + 1 file changed, 9 insertions(+) + +antirez in commit 447da44d: + Introduce repl_slave_ignore_maxmemory flag internally. + 3 files changed, 7 insertions(+) + +antirez in commit 868b2925: + Better variable meaning in processCommand(). + 1 file changed, 2 insertions(+), 2 deletions(-) + +antirez in commit 319f2ee6: + Re-apply rebased #2358. + 1 file changed, 1 insertion(+), 1 deletion(-) + +zhaozhao.zz in commit 22c166da: + block: format code + 1 file changed, 2 insertions(+), 2 deletions(-) + +zhaozhao.zz in commit c03c5913: + block: rewrite BRPOPLPUSH as RPOPLPUSH to propagate + 3 files changed, 5 insertions(+), 1 deletion(-) + +zhaozhao.zz in commit fcd5ef16: + networking: make setProtocolError simple and clear + 1 file changed, 11 insertions(+), 13 deletions(-) + +zhaozhao.zz in commit 656e4b2f: + networking: just move qb_pos instead of sdsrange in processInlineBuffer + 1 file changed, 2 insertions(+), 3 deletions(-) + +zhaozhao.zz in commit 2c7972ce: + networking: just return C_OK if multibulk processing saw a <= 0 length. + 1 file changed, 2 insertions(+), 5 deletions(-) + +zhaozhao.zz in commit 1203a04f: + adjust qbuf to 26 in test case for client list + 1 file changed, 1 insertion(+), 1 deletion(-) + +zhaozhao.zz in commit aff86fa1: + pipeline: do not sdsrange querybuf unless all commands processed + 2 files changed, 48 insertions(+), 40 deletions(-) + +Chris Lamb in commit 45a6c5be: + Use SOURCE_DATE_EPOCH over unreproducible uname + date calls. + 1 file changed, 3 insertions(+) + +Chris Lamb in commit 186df148: + Make some defaults explicit in the sentinel.conf for package maintainers + 1 file changed, 25 insertions(+) + +dejun.xdj in commit b59f04a0: + Streams: ID of xclaim command starts from the sixth argument. + 1 file changed, 1 insertion(+), 1 deletion(-) + +shenlongxing in commit a3f2437b: + Fix stream command paras + 2 files changed, 7 insertions(+), 7 deletions(-) + +antirez in commit df911235: + Fix AOF comment to report the current behavior. + 1 file changed, 3 insertions(+), 1 deletion(-) + + + +================================================================================ +Redis 5.0 RC4 Released Fri Aug 03 13:51:02 CEST 2018 +================================================================================ + +Upgrade urgency + + HIGH: Many non critical but important issues fixed. + CRITICAL for Stream users: Many important bugs fixed. + +Hi all, welcome to Redis 5.0 RC4. + +This release is a huge step forward in Redis 5 maturity and fixes a number +of issues. It also provides interesting improvements. Here I'll summarize +the biggest one, but laster you can find the full list of commits: + +Fixes: + +* A number of fixes related to Streams: stability and correctnes. +* Fix dbRandomKey() potential infinite loop. +* Improve eviction LFU/LRU when keys are created by INCR commands family. +* Active defragmentation is now working on Redis 5. +* Fix corner case in Redis CLuster / Sentinel failover, by resetting the + disconnection time with master in a more appropriate place. +* Use a private version of localtime() to avoid potential deadlocks. +* Different redis-cli non critical fixes. +* Fix rare replication stream corruption with disk-based replication. + +Improvements: + +* Sentinel: add an option to deny online script reconfiguration. +* Improved RESTORE command. +* Sentinel command renaming: allows to use Sentinel with Redis instances + that have non standard command names. +* CLIENT ID and CLIENT UNBLOCK. +* CLIENT LIST now supports a TYPE option. +* redis-cli --cluster now supports authentication. +* redis-trib is now deprecated (use redis-cli --cluster). +* Better slaves output buffers efficiency. +* Faster INFO when there are many clients connected. +* Dynamic HZ feature. +* Improvements in what the MEMORY command is able to report. +* Add year in log. (WARNING: may be incompatible with log scraping tools) +* Lazy freeing now works even when values are overwritten (for instance SET). +* Faster ZADD when elements scores are updated. +* Improvements to the test suite, including many new options. + +antirez in commit a4d1201e: + Test suite: add --loop option. + 1 file changed, 12 insertions(+), 5 deletions(-) + +antirez in commit 273d8191: + Test suite: new --stop option. + 1 file changed, 13 insertions(+), 4 deletions(-) + +antirez in commit fbbcc6a6: + Streams IDs parsing refactoring. + 1 file changed, 32 insertions(+), 17 deletions(-) + +antirez in commit 70c4bcb7: + Test: new sorted set skiplist order consistency. + 1 file changed, 26 insertions(+) + +antirez in commit 63addc5c: + Fix zslUpdateScore() edge case. + 1 file changed, 2 insertions(+), 2 deletions(-) + +antirez in commit 724740cc: + More commenting of zslUpdateScore(). + 1 file changed, 2 insertions(+) + +antirez in commit ddc87eef: + Explain what's the point of zslUpdateScore() in top comment. + 1 file changed, 5 insertions(+) + +antirez in commit 741f29ea: + Remove old commented zslUpdateScore() from source. + 1 file changed, 13 deletions(-) + +antirez in commit 20116836: + Optimize zslUpdateScore() as asked in #5179. + 1 file changed, 44 insertions(+) + +antirez in commit 8c297e8b: + zsetAdd() refactored adding zslUpdateScore(). + 1 file changed, 18 insertions(+), 7 deletions(-) + +dejun.xdj in commit bd2f3f6b: + Streams: rearrange the usage of '-' and '+' IDs in stream commands. + 1 file changed, 13 insertions(+), 13 deletions(-) + +dejun.xdj in commit c0c06b84: + Streams: add mmid_supp argument in streamParseIDOrReply(). + 1 file changed, 6 insertions(+), 2 deletions(-) + +antirez in commit ab237a8e: + Minor improvements to PR #5187. + 2 files changed, 13 insertions(+), 6 deletions(-) + +Oran Agra in commit 1ce3cf7a: + test suite conveniency improvements + 3 files changed, 79 insertions(+), 3 deletions(-) + +Oran Agra in commit 36622899: + add DEBUG LOG, to to assist test suite debugging + 1 file changed, 4 insertions(+) + +antirez in commit 83d4311a: + Cluster cron announce IP minor refactoring. + 1 file changed, 6 insertions(+), 3 deletions(-) + +shenlongxing in commit a633f8e1: + Fix cluster-announce-ip memory leak + 1 file changed, 3 insertions(+), 2 deletions(-) + +antirez in commit 24c45538: + Tranfer -> transfer typo fixed. + 1 file changed, 1 insertion(+), 1 deletion(-) + +zhaozhao.zz in commit c609f240: + refactor dbOverwrite to make lazyfree work + 4 files changed, 27 insertions(+), 12 deletions(-) + +antirez in commit 9e971739: + Refactoring: replace low-level checks with writeCommandsDeniedByDiskError(). + 2 files changed, 6 insertions(+), 13 deletions(-) + +antirez in commit 0e77cef0: + Fix writeCommandsDeniedByDiskError() inverted return value. + 1 file changed, 2 insertions(+), 2 deletions(-) + +antirez in commit acfe9d13: + Better top comment for writeCommandsDeniedByDiskError(). + 1 file changed, 8 insertions(+), 1 deletion(-) + +antirez in commit 4e933e00: + Introduce writeCommandsDeniedByDiskError(). + 2 files changed, 24 insertions(+) + +WuYunlong in commit 41607dfd: + Consider aof write error as well as rdb in lua script. + 1 file changed, 14 insertions(+), 4 deletions(-) + +Salvatore Sanfilippo in commit 1d073a64: + Merge pull request #5168 from rpv-tomsk/issue-5033 +Guy Korland in commit 2db31fd4: + Few typo fixes + 1 file changed, 13 insertions(+), 13 deletions(-) + +antirez in commit 64242757: + Add year in log. + 1 file changed, 1 insertion(+), 1 deletion(-) + +antirez in commit 50be4a1f: + Document dynamic-hz in the example redis.conf. + 1 file changed, 16 insertions(+) + +antirez in commit 9a76472d: + Make dynamic hz actually configurable. + 1 file changed, 9 insertions(+) + +antirez in commit a330d06c: + Control dynamic HZ via server configuration. + 2 files changed, 13 insertions(+), 6 deletions(-) + +antirez in commit d42602ff: + Dynamic HZ: adapt cron frequency to number of clients. + 2 files changed, 17 insertions(+), 5 deletions(-) + +antirez in commit 7b5f0223: + Dynamic HZ: separate hz from the configured hz. + 3 files changed, 15 insertions(+), 9 deletions(-) + +antirez in commit 037b00de: + Remove useless conditional from emptyDb(). + 1 file changed, 1 deletion(-) + +antirez in commit 0e97ae79: + Make emptyDb() change introduced in #4852 simpler to read. + 1 file changed, 8 insertions(+), 3 deletions(-) + +zhaozhao.zz in commit f7740faf: + optimize flushdb, avoid useless loops + 1 file changed, 5 insertions(+), 2 deletions(-) + +zhaozhao.zz in commit 0c008376: + Streams: fix xdel memory leak + 1 file changed, 1 insertion(+) + +antirez in commit dc600a25: + Example the magic +1 in migrateCommand(). + 1 file changed, 4 insertions(+) + +antirez in commit d6827ab6: + Make changes of PR #5154 hopefully simpler. + 1 file changed, 10 insertions(+), 5 deletions(-) + +WuYunlong in commit 89ec1453: + Do not migrate already expired keys. + 1 file changed, 6 insertions(+), 2 deletions(-) + +Pavel Rochnyack in commit cd25ed17: + INFO CPU: higher precision of reported values + 1 file changed, 8 insertions(+), 8 deletions(-) + +antirez in commit 6bfb4745: + Streams: refactoring of next entry seek in the iterator. + 1 file changed, 11 insertions(+), 7 deletions(-) + +zhaozhao.zz in commit 4724548e: + Streams: skip master fileds only when we are going forward in streamIteratorGetID + 1 file changed, 8 insertions(+), 5 deletions(-) + +Oran Agra in commit 4b79fdf1: + fix slave buffer test suite false positives + 1 file changed, 1 insertion(+), 1 deletion(-) + +antirez in commit a1e081f7: + string2ll(): better commenting. + 1 file changed, 6 insertions(+) + +dsomeshwar in commit 8b4fe752: + removing redundant check + 1 file changed, 3 deletions(-) + +antirez in commit 9e5bf047: + Restore string2ll() to original version. + 1 file changed, 7 insertions(+), 2 deletions(-) + +Oran Agra in commit c2ecdcde: + fix recursion typo in zmalloc_usable + 1 file changed, 1 insertion(+), 1 deletion(-) + +antirez in commit 4f742bd6: + string2ll(): remove duplicated check for special case. + 1 file changed, 1 insertion(+), 6 deletions(-) + +antirez in commit a4efac00: + string2ll(): test for NULL pointer in all the cases. + 1 file changed, 1 insertion(+), 1 deletion(-) + +antirez in commit 2c07c107: + Change 42 to 1000 as warning level for cached scripts. + 1 file changed, 3 insertions(+), 3 deletions(-) + +Itamar Haber in commit 270903d6: + Adds Lua overheads to MEMORY STATS, smartens the MEMORY DOCTOR + 3 files changed, 30 insertions(+), 4 deletions(-) + +Itamar Haber in commit faf3dbfc: + Adds memory information about the script's cache to INFO + 3 files changed, 12 insertions(+) + +antirez in commit 49841a54: + Fix merge errors. + 2 files changed, 7 deletions(-) + +antirez in commit 77a7ec72: + Merge branch 'unstable' into 5.0 branch +antirez in commit 4ff47a0b: + Top comment clientsCron(). + 1 file changed, 19 insertions(+), 4 deletions(-) + +antirez in commit aba68552: + Clarify that clientsCronTrackExpansiveClients() indexes may jump ahead. + 1 file changed, 9 insertions(+), 1 deletion(-) + +antirez in commit be88c0b1: + Rename INFO CLIENT max buffers field names for correctness. + 1 file changed, 2 insertions(+), 2 deletions(-) + +antirez in commit 0cf3794e: + Fix wrong array index variable in getExpansiveClientsInfo(). + 1 file changed, 1 insertion(+), 1 deletion(-) + +antirez in commit ea3a20c5: + Change INFO CLIENTS sections to report pre-computed max/min client buffers. + 1 file changed, 5 insertions(+), 5 deletions(-) + +antirez in commit 8f7e496b: + Rename var in clientsCronTrackExpansiveClients() for clarity. + 1 file changed, 3 insertions(+), 3 deletions(-) + +antirez in commit 8d617596: + Implement a function to retrieve the expansive clients mem usage. + 1 file changed, 12 insertions(+) + +antirez in commit 85a1b4f8: + clientsCronTrackExpansiveClients() actual implementation. + 1 file changed, 14 insertions(+), 1 deletion(-) + +antirez in commit d4c5fc57: + clientsCronTrackExpansiveClients() skeleton and ideas. + 1 file changed, 23 insertions(+) + +antirez in commit 1c95c075: + Make vars used only by INFO CLIENTS local to the block. + 1 file changed, 1 insertion(+), 1 deletion(-) + +Salvatore Sanfilippo in commit 16b8d364: + Merge pull request #4727 from kingpeterpaule/redis-fix-info-cli +antirez in commit 0aca977c: + Merge branch 'unstable' of github.com:/antirez/redis into unstable +antirez in commit 313b2240: + In addReplyErrorLength() only panic when replying to slave. + 1 file changed, 4 insertions(+), 3 deletions(-) + +antirez in commit 6183f059: + Refine comment in addReplyErrorLength() about replying to masters/slaves. + 1 file changed, 11 insertions(+) + +Salvatore Sanfilippo in commit 22e9321c: + Merge pull request #5138 from oranagra/improve_defrag_test +Oran Agra in commit f89c93c8: + make active defrag test more stable + 2 files changed, 6 insertions(+), 5 deletions(-) + +Salvatore Sanfilippo in commit 8213f64d: + Merge pull request #5122 from trevor211/allowWritesWhenAofDisabled +Salvatore Sanfilippo in commit 46fd9278: + Merge pull request #4237 from aspirewit/update-comment +antirez in commit 6201f7b4: + Streams: better error when $ is given with XREADGROUP. + 1 file changed, 5 insertions(+), 2 deletions(-) + +Salvatore Sanfilippo in commit 4bff45c7: + Merge pull request #5136 from 0xtonyxia/fix-xread-id-parse +antirez in commit afc7e08a: + Panic when we are sending an error to our master/slave. + 1 file changed, 5 insertions(+) + +Salvatore Sanfilippo in commit e03358c0: + Merge pull request #5135 from oranagra/rare_repl_corruption +dejun.xdj in commit 846cf12a: + Streams: remove meaningless if condition. + 1 file changed, 1 insertion(+), 1 deletion(-) + +dejun.xdj in commit 6501b6bb: + Streams: return an error message if using xreadgroup with '$' ID. + 1 file changed, 5 insertions(+) + +Oran Agra in commit d5559898: + fix rare replication stream corruption with disk-based replication + 3 files changed, 18 insertions(+), 9 deletions(-) + +antirez in commit cefe21d2: + dict.c: remove a few trailing spaces. + 1 file changed, 2 insertions(+), 2 deletions(-) + +Salvatore Sanfilippo in commit 4fc20992: + Merge pull request #5128 from kingpeterpaule/remove-one-loop-in-freeMemoryIfNeeded +Salvatore Sanfilippo in commit 9fbd49bb: + Merge pull request #5113 from 0xtonyxia/using-compare-func-instead +Salvatore Sanfilippo in commit cab39676: + Merge pull request #5127 from oranagra/sds_req_type +antirez in commit f9c84d6d: + Hopefully improve commenting of #5126. + 2 files changed, 22 insertions(+), 10 deletions(-) + +Salvatore Sanfilippo in commit e22a1218: + Merge pull request #5126 from oranagra/slave_buf_memory_2 +Salvatore Sanfilippo in commit 28dd8dd1: + Merge pull request #5132 from soloestoy/propagate-xdel-correctly +Oran Agra in commit bf680b6f: + slave buffers were wasteful and incorrectly counted causing eviction + 10 files changed, 182 insertions(+), 50 deletions(-) + +zhaozhao.zz in commit 73306c6f: + Streams: correctly propagate xdel if needed + 1 file changed, 7 insertions(+), 3 deletions(-) + +antirez in commit 103c5a1a: + Add a few comments to streamIteratorRemoveEntry(). + 1 file changed, 4 insertions(+) + +Salvatore Sanfilippo in commit a317f55d: + Merge pull request #5131 from soloestoy/optimize-xdel +antirez in commit 185e0d9c: + Modify XINFO field from last-id to last-generated-id. + 1 file changed, 1 insertion(+), 1 deletion(-) + +Salvatore Sanfilippo in commit 4215e74b: + Merge pull request #5129 from soloestoy/xinfo-show-last-id +zhaozhao.zz in commit c9324f81: + Streams: free lp if all elements are deleted + 1 file changed, 9 insertions(+), 4 deletions(-) + +paule in commit b6ce7d5d: + Update dict.c + 1 file changed, 4 insertions(+), 2 deletions(-) + +zhaozhao.zz in commit b4ba5ac8: + Streams: show last id for streams and groups + 1 file changed, 6 insertions(+), 2 deletions(-) + +peterpaule in commit 816fc6cb: + remove one ineffective loop in dictGetSomeKeys. + 1 file changed, 1 insertion(+), 1 deletion(-) + +Oran Agra in commit b05a22e2: + bugfix in sdsReqType creating 64bit sds headers on 32bit systems + 1 file changed, 3 insertions(+), 1 deletion(-) + +dejun.xdj in commit 491682a6: + Streams: using streamCompareID() instead of direct compare in block.c. + 1 file changed, 1 insertion(+), 4 deletions(-) + +dejun.xdj in commit a2177cd2: + Streams: add streamCompareID() declaration in stream.h. + 1 file changed, 1 insertion(+) + +dejun.xdj in commit 0484dbcf: + Streams: using streamCompareID() instead of direct compare. + 1 file changed, 2 insertions(+), 6 deletions(-) + +WuYunlong in commit 2d4366c5: + Accept write commands if persisting is disabled, event if we do have problems persisting on disk previously. + 1 file changed, 2 insertions(+), 1 deletion(-) + +Salvatore Sanfilippo in commit ab33bcd3: + Merge pull request #5120 from andrewsensus/leap-year-comment-patch-1 +antirez in commit 2352a519: + Test: XDEL fuzz testing. Remove and check stage. + 1 file changed, 15 insertions(+) + +antirez in commit 3d7d20b7: + Test: fix lshuffle by providing the "K" combinator. + 1 file changed, 2 insertions(+) + +antirez in commit 967ad364: + Test: add lshuffle in the Tcl utility functions set. + 1 file changed, 14 insertions(+) + +antirez in commit d6efd5fc: + Test: XDEL fuzz testing, stream creation. + 1 file changed, 20 insertions(+) + +andrewsensus in commit 8dc08ae2: + update leap year comment + 1 file changed, 1 insertion(+), 1 deletion(-) + +antirez in commit 69997153: + Merge branch 'unstable' of github.com:/antirez/redis into unstable +antirez in commit a93f8f09: + Test: XDEL basic test. + 1 file changed, 12 insertions(+) + +Salvatore Sanfilippo in commit a44a5934: + Merge pull request #5119 from trevor211/fixSlowlogConfig +WuYunlong in commit d6ba4fd5: + Fix config set slowlog-log-slower-than and condition in createLatencyReport + 2 files changed, 2 insertions(+), 2 deletions(-) + +WuYunlong in commit b3660be8: + Add test in slowlog.tcl + 1 file changed, 10 insertions(+) + +artix in commit d4182a0a: + Cluster Manager: more checks on --cluster-weight option. + 1 file changed, 12 insertions(+), 2 deletions(-) + +artix in commit d222eda9: + Redis-trib deprecated: it no longer works and it outputs a warning to the user. + 1 file changed, 103 insertions(+), 1804 deletions(-) + +artix in commit 513eb572: + Cluster Manager: auth support (-a argument). + 1 file changed, 41 insertions(+), 19 deletions(-) + +Salvatore Sanfilippo in commit f3980bb9: + Merge pull request #5115 from shenlongxing/patch-1 +Shen Longxing in commit c2a85fb3: + Delete unused role checking. + 1 file changed, 2 insertions(+), 6 deletions(-) + +Salvatore Sanfilippo in commit 4cb5bd4e: + Merge pull request #4820 from charpty/wip-serverc-simplify +antirez in commit 8d6b7861: + Add regression test for #5111. + 1 file changed, 15 insertions(+) + +antirez in commit b6260a02: + Streams: when re-delivering because of SETID, reset deliveries counter. + 1 file changed, 2 insertions(+), 2 deletions(-) + +antirez in commit a7c180e5: + Simplify duplicated NACK #5112 fix. + 1 file changed, 18 insertions(+), 21 deletions(-) + +Salvatore Sanfilippo in commit bf4def0f: + Merge pull request #5112 from 0xtonyxia/fix-xreadgroup-crash-after-setid +Salvatore Sanfilippo in commit 16770551: + Merge pull request #5114 from oranagra/defrag_32 +Oran Agra in commit 920158ec: + Active defrag fixes for 32bit builds (again) + 1 file changed, 2 insertions(+), 2 deletions(-) + +Salvatore Sanfilippo in commit f45e7901: + Merge pull request #4967 from JingchengLi/unstable +tengfeng in commit 9505dd20: + fix repeat argument issue and reduce unnessary loop times for redis-cli. + 1 file changed, 12 insertions(+), 7 deletions(-) + +antirez in commit 0420c327: + Merge branch 'unstable' of github.com:/antirez/redis into unstable +antirez in commit 28e95c7c: + Streams: fix typo "consumer". + 1 file changed, 1 insertion(+), 1 deletion(-) + +antirez in commit a8c1bb31: + Streams: fix new XREADGROUP sync logic. + 1 file changed, 13 insertions(+), 3 deletions(-) + +antirez in commit 1a02b5f6: + Streams: make blocking for > a truly special case. + 1 file changed, 29 insertions(+), 4 deletions(-) + +antirez in commit a71e8148: + Streams: send an error to consumers blocked on non-existing group. + 1 file changed, 5 insertions(+), 1 deletion(-) + +antirez in commit 09327f11: + Streams: fix unblocking logic into a consumer group. + 1 file changed, 24 insertions(+), 14 deletions(-) + +dejun.xdj in commit 3f8a3efe: + Streams: fix xreadgroup crash after xgroup SETID is sent. + 1 file changed, 20 insertions(+), 15 deletions(-) + +Salvatore Sanfilippo in commit 7239e9ca: + Merge pull request #5095 from 0xtonyxia/fix-indentation +dejun.xdj in commit 61f12973: + Bugfix: PEL is incorrect when consumer is blocked using xreadgroup with NOACK option. + 4 files changed, 6 insertions(+), 1 deletion(-) + +antirez in commit b67f0276: + redis-cli: fix #4990 additional argument in help. + 1 file changed, 1 insertion(+) + +antirez in commit 18d65849: + redis-cli: fix #5096 double error message. + 1 file changed, 1 insertion(+), 1 deletion(-) + +antirez in commit 84620327: + redis-cli: cliConnect() flags CC_FORCE and CC_QUIET. + 1 file changed, 23 insertions(+), 13 deletions(-) + +Amit Dey in commit a3a5a25f: + fixing broken link in CONTRIBUTING + 1 file changed, 1 insertion(+), 1 deletion(-) + +dejun.xdj in commit 289d8d9c: + CLIENT UNBLOCK: fix client unblock help message. + 1 file changed, 1 insertion(+), 1 deletion(-) + +minkikim89 in commit 62a4a8c1: + fix whitespace in redis-cli.c + 1 file changed, 362 insertions(+), 362 deletions(-) + +WuYunlong in commit 0a5805d7: + fix compile warning in addReplySubcommandSyntaxError + 1 file changed, 1 insertion(+), 1 deletion(-) + +antirez in commit cb78c842: + Use nolocks_localtime() for safer logging. + 2 files changed, 8 insertions(+), 2 deletions(-) + +antirez in commit 81778d91: + Cache timezone and daylight active flag for safer logging. + 2 files changed, 14 insertions(+), 1 deletion(-) + +antirez in commit 18d8205b: + Localtime: clarify is_leap_year() working with comments. + 1 file changed, 4 insertions(+), 4 deletions(-) + +antirez in commit 29644144: + Localtime: fix comment about leap year. + 1 file changed, 1 insertion(+), 1 deletion(-) + +antirez in commit 0ea39aa4: + Localtime: fix daylight saving adjustment. Use * not +. + 1 file changed, 1 insertion(+), 1 deletion(-) + +antirez in commit 6614d305: + Localtime: fix daylight time documentation and computation. + 1 file changed, 14 insertions(+), 4 deletions(-) + +dejun.xdj in commit 46f5a2ca: + Fix indentation. + 2 files changed, 14 insertions(+), 14 deletions(-) + +antirez in commit 243c5a7a: + Localtime: add a test main() function to check the output. + 1 file changed, 15 insertions(+), 1 deletion(-) + +antirez in commit c25ee35a: + Localtime: day of month is 1 based. Convert from 0 based "days". + 1 file changed, 2 insertions(+), 2 deletions(-) + +antirez in commit b9f33830: + Localtime: fix timezone adjustment. + 1 file changed, 2 insertions(+), 1 deletion(-) + +antirez in commit 0c12cbed: + Localtime: compute year, month and day of the month. + 1 file changed, 26 insertions(+) + +antirez in commit 06ca400f: + Localtime: basics initial calculations. Year missing. + 1 file changed, 30 insertions(+), 2 deletions(-) + +antirez in commit 6a529067: + Localtime function skeleton and file added. + 1 file changed, 44 insertions(+) + +Jack Drogon in commit 93238575: + Fix typo + 40 files changed, 99 insertions(+), 99 deletions(-) + +antirez in commit 94b3ee61: + Clarify the pending_querybuf field of clients. + 1 file changed, 4 insertions(+), 3 deletions(-) + +antirez in commit 549b8b99: + Improve style of PR #5084. + 1 file changed, 8 insertions(+), 2 deletions(-) + +Salvatore Sanfilippo in commit 526b30a7: + Merge pull request #5084 from chendq8/pending-querybuf +antirez in commit 677d10b2: + Set repl_down_since to zero on state change. + 1 file changed, 2 insertions(+), 1 deletion(-) + +Salvatore Sanfilippo in commit 02e38516: + Merge pull request #5081 from trevor211/fixClusterFailover +chendianqiang in commit cbb2ac07: + Merge branch 'unstable' into pending-querybuf +antirez in commit 2edcafb3: + addReplySubSyntaxError() renamed to addReplySubcommandSyntaxError(). + 12 files changed, 14 insertions(+), 14 deletions(-) + +Salvatore Sanfilippo in commit bc6a0045: + Merge pull request #4998 from itamarhaber/module_command_help +Salvatore Sanfilippo in commit ee09b5ed: + Merge pull request #5071 from akshaynagpal/patch-2 +Salvatore Sanfilippo in commit f03ad962: + Merge pull request #5068 from shenlongxing/fix-rename-command +Salvatore Sanfilippo in commit e4881cd0: + Merge pull request #5090 from trevor211/test_helper_tcl +WuYunlong in commit 2833cfbe: + fix tests/test_helper.tcl with --wait-server option. Issue #5063 added --wait-server option, but can not work. + 1 file changed, 1 deletion(-) + +chendianqiang in commit 7de1ada0: + limit the size of pending-querybuf in masterclient + 4 files changed, 48 insertions(+) + +WuYunlong in commit 2e167f7d: + fix server.repl_down_since resetting, so that slaves could failover automatically as expected. + 1 file changed, 1 insertion(+), 1 deletion(-) + +WuYunlong in commit aeb7bc3e: + cluster.tcl: Add master consecutively down test. + 1 file changed, 77 insertions(+) + +antirez in commit d751d98b: + Change CLIENT LIST TYPE help string. + 1 file changed, 2 insertions(+), 2 deletions(-) + +Salvatore Sanfilippo in commit a0b05a04: + Merge pull request #5075 from soloestoy/client-list-types +Salvatore Sanfilippo in commit aa2c390e: + Merge pull request #5074 from soloestoy/fix-compile-warning +Salvatore Sanfilippo in commit a4ef94d2: + Merge pull request #5076 from 0xtonyxia/add-no-auth-warning-option +dejun.xdj in commit 9f185626: + Check if password is used on command line interface. + 1 file changed, 1 insertion(+), 1 deletion(-) + +dejun.xdj in commit 1139070a: + Fix trailing white space. + 1 file changed, 1 insertion(+), 1 deletion(-) + +dejun.xdj in commit bbd0ca95: + Fix code format issue. + 1 file changed, 4 insertions(+), 4 deletions(-) + +dejun.xdj in commit 7becf54e: + Don't output password warning message when --no-auth-warning is used. + 1 file changed, 10 insertions(+), 1 deletion(-) + +dejun.xdj in commit bde05e9c: + Avoid -Woverlength-strings compile warning. + 1 file changed, 5 insertions(+), 3 deletions(-) + +antirez in commit 5baf50d8: + Rax library updated (node callback). + 2 files changed, 19 insertions(+), 5 deletions(-) + +dejun.xdj in commit 0b74fd67: + Add --no-auth-warning help message. + 1 file changed, 2 insertions(+) + +zhaozhao.zz in commit b9cbd04b: + clients: add type option for client list + 4 files changed, 20 insertions(+), 6 deletions(-) + +zhaozhao.zz in commit f5538642: + clients: show pubsub flag in client list + 1 file changed, 1 insertion(+) + +zhaozhao.zz in commit 1fcf2737: + fix some compile warnings + 2 files changed, 2 insertions(+), 2 deletions(-) + +Akshay Nagpal in commit 007e3cbd: + Added link to Google Group + 1 file changed, 3 insertions(+), 1 deletion(-) + +antirez in commit ab55f9da: + Make CLIENT HELP output nicer to the eyes. + 1 file changed, 11 insertions(+), 11 deletions(-) + +antirez in commit 75f1a7bd: + Merge branch 'unstable' of github.com:/antirez/redis into unstable +antirez in commit 4a70ff74: + Add unblock in CLIENT HELP. + 1 file changed, 1 insertion(+) + +shenlongxing in commit 3c27db1c: + fix empty string for sentinel rename-command + 1 file changed, 5 insertions(+) + +Salvatore Sanfilippo in commit f7b21bc7: + Merge pull request #5066 from oranagra/defrag_jemalloc5_fix +Salvatore Sanfilippo in commit 730a4cfa: + Merge pull request #5067 from mpaltun/mpaltun-doc-fix +antirez in commit 2214043b: + CLIENT UNBLOCK: support unblocking by error. + 1 file changed, 22 insertions(+), 3 deletions(-) + +Mustafa Paltun in commit 010dc172: + Update t_stream.c + 1 file changed, 2 insertions(+), 2 deletions(-) + +Mustafa Paltun in commit 6d0acb33: + Update help.h + 1 file changed, 1 insertion(+), 1 deletion(-) + +Oran Agra in commit de495ee7: + minor fix in creating a stream NACK for rdb and defrag tests + 2 files changed, 2 insertions(+), 2 deletions(-) + +antirez in commit 71295ee3: + CLIENT UNBLOCK implemented. + 1 file changed, 22 insertions(+) + +antirez in commit fb39bfd7: + Take clients in a ID -> Client handle dictionary. + 3 files changed, 6 insertions(+) + +antirez in commit ed65d734: + CLIENT ID implemented. + 1 file changed, 4 insertions(+) + +Salvatore Sanfilippo in commit 345b4809: + Merge pull request #5063 from oranagra/test_suite_improvements +Salvatore Sanfilippo in commit 35c5f3fa: + Merge pull request #5065 from oranagra/defrag_jemalloc5 +Oran Agra in commit 5616d4c6: + add active defrag support for streams + 6 files changed, 230 insertions(+), 25 deletions(-) + +Oran Agra in commit e8099cab: + add defrag hint support into jemalloc 5 + 3 files changed, 43 insertions(+) + +Oran Agra in commit 751eea24: + test suite infra improvements and fix + 2 files changed, 19 insertions(+) + +Salvatore Sanfilippo in commit bb666d44: + Merge pull request #5027 from tigertv/unstable +antirez in commit b9058c73: + Merge branch 'unstable' of github.com:/antirez/redis into unstable +antirez in commit 43831779: + Sentinel: test command renaming feature. + 1 file changed, 10 insertions(+) + +Salvatore Sanfilippo in commit eb052ba9: + Merge pull request #5059 from guybe7/fix_restore_warning +antirez in commit 27178a3f: + Fix type of argslen in sendSynchronousCommand(). + 1 file changed, 1 insertion(+), 1 deletion(-) + +antirez in commit 1f1e724f: + Remove black space. + 1 file changed, 1 insertion(+), 1 deletion(-) + +Salvatore Sanfilippo in commit aa5eaad4: + Merge pull request #5037 from madolson/repl-auth-fix +antirez in commit 3cf8dd2c: + Sentinel: fix SENTINEL SET error reporting. + 1 file changed, 18 insertions(+), 9 deletions(-) + +Madelyn Olson in commit 45731edc: + Addressed comments + 1 file changed, 1 insertion(+), 1 deletion(-) + +Madelyn Olson in commit e8d68b6b: + Fixed replication authentication with whitespace in password + 1 file changed, 12 insertions(+), 5 deletions(-) + +antirez in commit fc0c9c80: + Sentinel: drop the renamed-command entry in a more natural way. + 1 file changed, 4 insertions(+), 7 deletions(-) + +antirez in commit 8ba670f5: + Sentinel command renaming: document it into sentinel.conf. + 1 file changed, 19 insertions(+) + +antirez in commit a8a76bda: + Merge branch 'unstable' of github.com:/antirez/redis into unstable +antirez in commit 2358de68: + Sentinel command renaming: use case sensitive hashing for the dict. + 1 file changed, 2 insertions(+), 1 deletion(-) + +antirez in commit a9c50088: + Sentinel command renaming: fix CONFIG SET event logging. + 1 file changed, 17 insertions(+), 1 deletion(-) + +antirez in commit b72cecd7: + Sentinel command renaming: fix CONFIG SET after refactoring. + 1 file changed, 5 insertions(+), 5 deletions(-) + +antirez in commit 91a384a5: + Sentinel command renaming: implement SENTINEL SET. + 1 file changed, 19 insertions(+) + +antirez in commit 903582dd: + Sentinel: make SENTINEL SET able to handle different arities. + 1 file changed, 19 insertions(+), 12 deletions(-) + +antirez in commit c303e768: + Sentinel command renaming: config rewriting. + 1 file changed, 12 insertions(+) + +antirez in commit 60df7dbe: + Sentinel command renaming: rename-command option parsing. + 1 file changed, 11 insertions(+) + +antirez in commit 72e8a33b: + Sentinel command renaming: base machanism implemented. + 1 file changed, 64 insertions(+), 15 deletions(-) + +Guy Benoish in commit dfcc20f4: + Fix compiler warning in restoreCommand + 1 file changed, 1 insertion(+), 1 deletion(-) + +Salvatore Sanfilippo in commit cf7fcdbe: + Merge pull request #4634 from soloestoy/special-auth +Salvatore Sanfilippo in commit 70b7fa2c: + Merge pull request #5049 from youjiali1995/fix-load-rdb +Salvatore Sanfilippo in commit 54d66d39: + Merge pull request #5053 from michael-grunder/zpopminmax-keypos +Salvatore Sanfilippo in commit 199e704a: + Merge pull request #5050 from shenlongxing/fix-typo +michael-grunder in commit db6b99f9: + Update ZPOPMIN/ZPOPMAX command declaration + 1 file changed, 2 insertions(+), 2 deletions(-) + +Salvatore Sanfilippo in commit a16aa03a: + Merge pull request #5051 from oranagra/streams_mem_estimate +Oran Agra in commit 20e10dc7: + fix streams memory estimation, missing raxSeek + 1 file changed, 2 insertions(+), 1 deletion(-) + +shenlongxing in commit ec55df11: + fix typo + 4 files changed, 4 insertions(+), 4 deletions(-) + +youjiali1995 in commit df6644fe: + Fix rdbLoadIntegerObject() to create shared objects when needed. + 1 file changed, 1 insertion(+), 1 deletion(-) + +Salvatore Sanfilippo in commit 1527bcad: + Merge pull request #5036 from bepahol/unstable +Salvatore Sanfilippo in commit c1e82405: + Merge pull request #5039 from oranagra/rdb_dbsize_hint +Salvatore Sanfilippo in commit 79f55eed: + Merge pull request #5040 from oranagra/memrev64ifbe_fix +Salvatore Sanfilippo in commit c6f4118c: + Merge pull request #5045 from guybe7/restore_fix +Guy Benoish in commit b5197f1f: + Enhance RESTORE with RDBv9 new features + 5 files changed, 100 insertions(+), 22 deletions(-) + +Salvatore Sanfilippo in commit c6fdebf5: + Merge pull request #5042 from oranagra/malloc_usable_size_libc +Oran Agra in commit 482785ac: + add malloc_usable_size for libc malloc + 2 files changed, 8 insertions(+), 3 deletions(-) + +Salvatore Sanfilippo in commit 4da29630: + Merge pull request #5023 from FX-HAO/unstable +antirez in commit e7219025: + Test RDB stream encoding saving/loading. + 1 file changed, 17 insertions(+) + +Salvatore Sanfilippo in commit 5f5e1199: + Merge pull request #5041 from oranagra/redis-rdb-check_rdbLoadMillisecondTime +antirez in commit 4848fbec: + Modules: convert hash to hash table for big objects. + 1 file changed, 3 insertions(+) + +Oran Agra in commit f31b0405: + fix redis-rdb-check to provide proper arguments to rdbLoadMillisecondTime + 2 files changed, 3 insertions(+), 2 deletions(-) + +antirez in commit 333c98c4: + AOF: remove no longer used variable "now". + 1 file changed, 1 deletion(-) + +antirez in commit e94b2053: + Modify clusterRedirectClient() to handle ZPOP and XREAD. + 1 file changed, 5 insertions(+), 1 deletion(-) + +Oran Agra in commit 26229aa6: + use safe macro (non empty) in memrev64ifbe to eliminate empty if warning + 1 file changed, 3 insertions(+), 3 deletions(-) + +Oran Agra in commit 5cd3c952: + 64 bit RDB_OPCODE_RESIZEDB in rdb saving + 1 file changed, 3 insertions(+), 7 deletions(-) + +antirez in commit ba92b517: + Remove AOF optimization to skip expired keys. + 1 file changed, 3 deletions(-) + +Benjamin Holst in commit 36524060: + Update README.md + 1 file changed, 1 insertion(+), 1 deletion(-) + +antirez in commit 44571088: + Merge branch 'unstable' of github.com:/antirez/redis into unstable +antirez in commit 6967d0bd: + Revert fix #4976 just leaving the flush() part. + 1 file changed, 1 insertion(+), 5 deletions(-) + +antirez in commit 0ed0dc3c: + Fix incrDecrCommand() to create shared objects when needed. + 1 file changed, 1 insertion(+), 1 deletion(-) + +antirez in commit bd92389c: + Refactor createObjectFromLongLong() to be suitable for value objects. + 2 files changed, 33 insertions(+), 2 deletions(-) + +Salvatore Sanfilippo in commit 3518bb66: + Merge pull request #5020 from shenlongxing/fix-config +antirez in commit 20766608: + Streams: fix xreadGetKeys() for correctness. + 1 file changed, 19 insertions(+), 5 deletions(-) + +Salvatore Sanfilippo in commit e670ccff: + Merge pull request #4857 from youjiali1995/fix-command-getkeys +antirez in commit a0b27dae: + Streams: fix xreadGetKeys() buffer overflow. + 1 file changed, 1 insertion(+), 1 deletion(-) + +antirez in commit 62f9ac6f: + Streams: Change XADD MAXLEN handling of values <= 0. + 1 file changed, 3 insertions(+), 3 deletions(-) + +Max Vetrov in commit d4c4f20a: + Update sort.c + 1 file changed, 1 insertion(+), 3 deletions(-) + +antirez in commit 79a1c19a: + XADD MAXLEN should return an error for values < 0. + 1 file changed, 5 insertions(+) + +Salvatore Sanfilippo in commit 2e0ab4a8: + Merge pull request #4976 from trevor211/fixDebugLoadaof +Salvatore Sanfilippo in commit 94658303: + Merge pull request #4758 from soloestoy/rdb-save-incremental-fsync +antirez in commit 6a66b93b: + Sentinel: add an option to deny online script reconfiguration. + 2 files changed, 41 insertions(+) + +antirez in commit d353023a: + Merge branch 'unstable' of github.com:/antirez/redis into unstable +antirez in commit d6e8fe77: + Fix infinite loop in dbRandomKey(). + 1 file changed, 13 insertions(+) + +Salvatore Sanfilippo in commit 40d5df65: + Merge pull request #5008 from zwkno1/unstable +Salvatore Sanfilippo in commit 8bc3ffcb: + Merge pull request #5021 from soloestoy/fix-exists +Salvatore Sanfilippo in commit 6c7847a1: + Merge pull request #5018 from soloestoy/optimize-reply +antirez in commit 1e92fde3: + Fix SCAN bug regression test, avoiding empty SREM call. + 1 file changed, 1 insertion(+), 1 deletion(-) + +Fuxin Hao in commit a4f658b2: + Fix update_zmalloc_stat_alloc in zrealloc + 1 file changed, 1 insertion(+), 1 deletion(-) + +================================================================================ +Redis 5.0 RC3 Released Wed Jun 14 9:51:44 CEST 2018 +================================================================================ + +Upgrade urgency LOW: + +This release fixes compilation of Redis RC2. For an error the commit from unstable +updating the Rax library was not merged into the 5.0 branch. + +================================================================================ +Redis 5.0 RC2 Released Wed Jun 13 12:49:13 CEST 2018 +================================================================================ + +Upgrade urgency CRITICAL: This release fixes important security issues. + HIGH: This release fixes a SCAN commands family bug. + MODERATE: This release fixes a PSYNC2 edge case with expires. + MODERATE: Sentinel related fixes. + LOW: All the other issues + +NOTE: This release breaks API compatibility with certain APIs that were +introduced in Redis 5.0 RC1. Notably ZPOP* now returns score/element in reverse +order. XINFO special form was removed, now XINFO STREAM must be +used to obtain general information about the stream. + +Redis 5.0 RC2 ixes a number of important issues: + +* Important security issues related to the Lua scripting engine. + Please check https://github.com/antirez/redis/issues/5017 + for more information. + +* A bug with SCAN, SSCAN, HSCAN and ZSCAN, that may not return all the elements. + We also add a regression test that can trigger the issue often when present, and + may in theory be able to find unrelated regressions. + +* A PSYNC2 bug is fixed: Redis should not expire keys when saving RDB files + because otherwise it is no longer possible to use such RDB file as a base + for partial resynchronization. It no longer represents the right state. + +* Compatibility of AOF with RDB preamble when the RDB checksum is disabled. + +* Sentinel bug that in some cases prevented Sentinel to detect that the master + was down immediately. A delay was added to the detection. + +* XREADGROUP would crash when the master had attacked slaves. + +* Replication and events generation of several streams command were fixed. + +* XREVRANGE fixed, in some cases it could not return elements, or crash the + server, or in general not behave correctly. + +* ZPOP can now unblock multiple clients in a sane way. + +* Other minor issues. + +Moreover this release adds new features: + +* XGROUP DESTROY and XGROUP SETID. + +* RDB loading speedup. + +* Configurable stream macro node limits (number of elements / bytes). + +* More smaller improvements. + +The following is the list of commits composing the release, please check +the commit messages and authors for credits. + +antirez in commit 9fdcc159: + Security: fix redis-cli buffer overflow. + 1 file changed, 16 insertions(+), 11 deletions(-) + +antirez in commit cf760071: + Security: fix Lua struct package offset handling. + 1 file changed, 6 insertions(+), 2 deletions(-) + +antirez in commit a57595ca: + Security: more cmsgpack fixes by @soloestoy. + 1 file changed, 7 insertions(+) + +antirez in commit 8783fb94: + Security: update Lua struct package for security. + 1 file changed, 23 insertions(+), 23 deletions(-) + +antirez in commit 8cb9344b: + Security: fix Lua cmsgpack library stack overflow. + 1 file changed, 3 insertions(+) + +赵磊 in commit 59080f60: + Fix dictScan(): It can't scan all buckets when dict is shrinking. + 1 file changed, 14 insertions(+), 11 deletions(-) + +dejun.xdj in commit ac2a824a: + Fix redis-cli memory leak when sending set preference command. + 1 file changed, 2 insertions(+) + +dejun.xdj in commit c7197ff5: + Check if the repeat value is positive in while loop of cliSendCommand(). + 1 file changed, 1 insertion(+), 1 deletion(-) + +dejun.xdj in commit 3f77777f: + Change the type of repeat argument to long for function cliSendCommand. + 1 file changed, 1 insertion(+), 1 deletion(-) + +dejun.xdj in commit 7a565d72: + Fix negtive repeat command value issue. + 1 file changed, 11 insertions(+), 3 deletions(-) + +dejun.xdj in commit 64bf60fb: + Detect and stop saving history for auth command with repeat option. + 1 file changed, 17 insertions(+), 10 deletions(-) + +dejun.xdj in commit 5bed12aa: + Change the warning message a little bit to avoid trademark issuses. + 1 file changed, 1 insertion(+), 1 deletion(-) + +dejun.xdj in commit d71c4961: + Stop saving auth command in redis-cli history. + 1 file changed, 4 insertions(+), 2 deletions(-) + +dejun.xdj in commit fca99e41: + Add warning message when using password on command line + 1 file changed, 1 insertion(+) + +antirez in commit 01407a3a: + Don't expire keys while loading RDB from AOF preamble. + 3 files changed, 5 insertions(+), 5 deletions(-) + +WuYunlong in commit fb5408cf: + Fix rdb save by allowing dumping of expire keys, so that when we add a new slave, and do a failover, eighter by manual or not, other local slaves will delete the expired keys properly. + 2 files changed, 3 insertions(+), 7 deletions(-) + +antirez in commit 0b8b6df4: + Backport hiredis issue 525 fix to compile on FreeBSD. + 1 file changed, 1 insertion(+), 1 deletion(-) + +antirez in commit e98627c5: + Add INIT INFO to the provided init script. + 1 file changed, 8 insertions(+) + +antirez in commit 17f5de89: + Fix ae.c when a timer finalizerProc adds an event. + 2 files changed, 10 insertions(+), 6 deletions(-) + +antirez in commit 266e6423: + Sentinel: fix delay in detecting ODOWN. + 1 file changed, 9 insertions(+), 5 deletions(-) + +zhaozhao.zz in commit eafaf172: + AOF & RDB: be compatible with rdbchecksum no + 1 file changed, 9 insertions(+), 7 deletions(-) + +huijing.whj in commit 4630da37: + fix int overflow problem in freeMemoryIfNeeded + 1 file changed, 1 insertion(+), 1 deletion(-) + +================================================================================ +Redis 5.0 RC1 Released Tue May 29 14:14:11 CEST 2018 +================================================================================ + +Upgrade urgency LOW: This is the first RC of Redis 5. + +Introduction to the Redis 5 release +=================================== + +Redis 5 is a release focused on a few important features. While Redis 4 +was very very focused on operations, Redis 5 changes are mostly user-facing, +with the implementation of new data types and operations on top of existing +types. The following are the major features of this release: + +1. The new Stream data type. https://redis.io/topics/streams-intro +2. New Redis modules APIs: Timers, Cluster and Dictionary APIs. +3. RDB now store LFU and LRU information. +4. The cluster manager was ported from Ruby (redis-trib.rb) to C code + inside redis-cli. Check `redis-cli --cluster help` for more info. +5. New sorted set commands: ZPOPMIN/MAX and blocking variants. +6. Active defragmentation version 2. +7. Improvemenets in HyperLogLog implementations. +8. Better memory reporting capabilities. +9. Many commands with sub-commands now have an HELP subcommand. +10. Better performances when clients connect and disconnect often. +11. Many bug fixes and other random improvements. +12. Jemalloc was upgraded to version 5.1 +13. CLIENT UNBLOCK and CLIENT ID. +14. The LOLWUT command was added. http://antirez.com/news/123 +15. We no longer use the "slave" word if not for API backward compatibility. +16. Differnet optimizations in the networking layer. +17. Lua improvements: + - Better propagation of Lua scripts to slaves / AOF. + - Lua scripts can now timeout and get in -BUSY state in the slave as well. +18. Dynamic HZ to balance idle CPU usage with responsiveness. +19. The Redis core was refactored and improved in many ways. + +Thanks to all the users and developers who made this release possible. +We'll follow up with more RC releases, until the code looks production ready +and we don't get reports of serious issues for a while. + +A special thank you for the amount of work put into this release +(in decreasing number of commits) by: + +Fabio Nicotra, +Soloestoy +Itamar Haber +Oran Agra +Dvir Volk +dejun.xdj +Guy Benoish +Charsyam +Otmar Ertl +Jan-Erik Rediger +Spinlock + +Migrating from 4.0 to 5.0 +========================= + +Redis 4.0 is mostly a strict subset of 5.0, you should not have any problem +upgrading your application from 4.0 to 5.0. However this is a list of small +non-backward compatible changes introduced in the 5.0 release: + +* redis-cli now implements the cluster management tool. We still ship the + old redis-trib, but new fixes will be implemented only in redis-cli. + See `redis-cli --cluster help` for more info. + +* The RDB format changed. Redis 5.0 is still able to read 4.0 (and all the + past versions) files, but not the other way around. + +* Certain log formats and sentences are different in Redis 5.0. + +* Now by default maxmemory is ignored by slaves, and used only once a slave + is promoted to master. It means that in setups where you want slaves to + enforce maxmemory in an independent way from the master (that will anyway + stream the key eviction DEL commands), you should active this feature manually + and make sure you understand that it breaks consistency if writes are not + always idempotent. TLDR: the new behavior is much better for 99.999% of use + cases, revert it if you really know what you are doing. + +* Scripts are only replicated by their *effects* and not by sending EVAL/EVALSHA + to slaves or the AOF log itself. This is much better in the general case + and in the future we want to totally remove the other possiblity of + propagating scripts the old way (as EVAL). However you can still turn this + back to the default via the non-documented (if not here) Redis configuration + directive "lua-replicate-commands yes" or + "DEBUG lua-always-replicate-commands 0". However note that Redis 6 may + completely remove such feature. + +* Because of the above change related to scripts replication, certain Redis + commands that in Redis 4 had their result ordered lexicographically before + being passed to Lua via the return value of redis.call(), now have a behavior + more similar to calling the commands directly from a normal client. For + instance the ordering of elements returned by SMEMBERS or SDIFF is now + undetermined in Lua, exactly as it is by default when calling the commands + from a non-scripting context. + +-------------------------------------------------------------------------------- + +Credits: For each release, a list of changes with the relative author is +provided. Where not specified the implementation and design is done by +Salvatore Sanfilippo. Thanks to Redis Labs for making all this possible. +Also many thanks to all the other contributors and the amazing community +we have. + +Commit messages may contain additional credits. + +Enjoy, +Salvatore diff --git a/Redis-x64-5.0.14.1/EventLog.dll b/Redis-x64-5.0.14.1/EventLog.dll new file mode 100644 index 0000000..3cf1453 Binary files /dev/null and b/Redis-x64-5.0.14.1/EventLog.dll differ diff --git a/Redis-x64-5.0.14.1/README.txt b/Redis-x64-5.0.14.1/README.txt new file mode 100644 index 0000000..b06e115 --- /dev/null +++ b/Redis-x64-5.0.14.1/README.txt @@ -0,0 +1,19 @@ +Redis for Windows - https://github.com/tporadowski/redis +======================================================== + +This version of Redis (https://redis.io/) is an unofficial port to Windows OS +based on work contributed by Microsoft Open Technologies Inc. It is maintained +by Tomasz Poradowski (tomasz@poradowski.com, http://www.poradowski.com/en/). + +Contents of this package: +- *.exe - various Redis for Windows executables compiled for x64 platfrom, +- *.pdb - accompanying PDB files useful for debugging purposes, +- license.txt - license information (BSD-like), +- RELEASENOTES.txt - Windows-specific release notes, +- 00-RELEASENOTES - changelog of original Redis project, those changes are + ported back to this Windows version. + +For more information - please visit https://github.com/tporadowski/redis + +If you find this version of Redis useful and would like to support ongoing +development - please consider sponsoring my work at https://github.com/sponsors/tporadowski diff --git a/Redis-x64-5.0.14.1/RELEASENOTES.txt b/Redis-x64-5.0.14.1/RELEASENOTES.txt new file mode 100644 index 0000000..bdcebc6 --- /dev/null +++ b/Redis-x64-5.0.14.1/RELEASENOTES.txt @@ -0,0 +1,99 @@ +Redis for Windows - https://github.com/tporadowski/redis +======================================================== + +This file provides information about Windows-specific changes to Redis. +For release notes related to original Redis project - please see 00-RELEASENOTES. + +-------------------------------------------------------- + +2021-10-18: Redis 5.0.14 for Windows +https://github.com/tporadowski/redis/releases/tag/v5.0.14 + +Bugfix/maintenance release of Redis for Windows, updated to be in sync with +redis/5.0.14 (https://github.com/redis/redis/releases/tag/5.0.14). +Additionally "SCRIPT DEBUG SYNC" is now available. + +-------------------------------------------------------- + +2020-11-08: Redis 5.0.10 for Windows +https://github.com/tporadowski/redis/releases/tag/v5.0.10 + +Bugfix/maintenance release of Redis for Windows, updated to be in sync with +redis/5.0.10 (https://github.com/redis/redis/releases/tag/5.0.10) + +NOTE: active memory defragmentation feature ("activedefrag" option) is turned OFF. + +-------------------------------------------------------- + +2020-05-02: Redis 5.0.9 for Windows +https://github.com/tporadowski/redis/releases/tag/v5.0.9 + +First release of Redis 5.x for Windows, updated to be in sync with antirez/5.0.9. + +-------------------------------------------------------- + +2020-01-26: Redis 4.0.14.2 for Windows +https://github.com/tporadowski/redis/releases/tag/v4.0.14.2 + +This is a hotfix release of 4.0.14 branch that fixes #50 related to running in +Sentinel mode. + +-------------------------------------------------------- + +2020-01-15: Redis 4.0.14.1 for Windows +https://github.com/tporadowski/redis/releases/tag/v4.0.14.1 + +This is a hotfix release of 4.0.14 branch that fixes 2 Windows-specific issues: + + * #46 - added support for older Windows versions (prior Windows 8 and Windows Server 2012) + * #47 - fixed problem with parsing command-line arguments. + +-------------------------------------------------------- + +2019-08-29: Redis 4.0.14 for Windows +https://github.com/tporadowski/redis/releases/tag/v4.0.14 + +Redis 4.0.14 for Windows is a merge of Windows-specific changes from latest (unsupported) 3.2.100 release from MSOpenTech and original Redis 4.0.14. + +-------------------------------------------------------- + +2018-10-01: Redis for Windows 4.0.2.3 (alpha) + +This 4.0.2.3 release is still an alpha version, but contains enhancements and fixes for: + + * #14: decrease logging verbosity of some cluster-related messages + * #23: ZRANK/ZREVRANK bugfix (win-port only) + * failed unit tests (bdcf80e). + +-------------------------------------------------------- + +2018-03-26: Redis for Windows 4.0.2.2 (alpha) +https://github.com/tporadowski/redis/releases/tag/v4.0.2.2-alpha + +This 4.0.2.2 release is still an alpha version, but contains a fix to issue #12 +(crash when rewriting AOF file - this issue was specific to Windows port only). + +-------------------------------------------------------- + +2018-03-17: Redis for Windows 4.0.2.1 (alpha) +https://github.com/tporadowski/redis/releases/tag/v4.0.2.1-alpha + +This 4.0.2.1 release is still an alpha version, but contains a fix to issue #11, +which was related to sending back larger amounts of data to Redis clients +(this issue was specific to Windows port only). + +-------------------------------------------------------- + +2017-11-22: Redis 4.0.2 for Windows (alpha) +https://github.com/tporadowski/redis/releases/tag/v4.0.2-alpha + +Alpha version of Redis 4.0.2 for Windows. + +Redis 4.0.2 for Windows is a merge of Windows-specific changes from latest (unsupported) 3.2.100 release +from MSOpenTech and Redis 4.0.2 and this alpha release consists of: + + * all Redis 4.0.2 features except modules, + * all executables of Redis (redis-server, redis-cli, redis-benchmark, redis-check-aof, redis-check-rdb). + +Main difference to official Redis 4.0.2 (except no support for modules at the moment) is old version +of jemalloc-win dependency, which is planned to be updated to the same version in beta release. diff --git a/Redis-x64-5.0.14.1/dump.rdb b/Redis-x64-5.0.14.1/dump.rdb new file mode 100644 index 0000000..fea444d Binary files /dev/null and b/Redis-x64-5.0.14.1/dump.rdb differ diff --git a/Redis-x64-5.0.14.1/redis-benchmark.exe b/Redis-x64-5.0.14.1/redis-benchmark.exe new file mode 100644 index 0000000..b7e27b9 Binary files /dev/null and b/Redis-x64-5.0.14.1/redis-benchmark.exe differ diff --git a/Redis-x64-5.0.14.1/redis-benchmark.pdb b/Redis-x64-5.0.14.1/redis-benchmark.pdb new file mode 100644 index 0000000..0682a66 Binary files /dev/null and b/Redis-x64-5.0.14.1/redis-benchmark.pdb differ diff --git a/Redis-x64-5.0.14.1/redis-check-aof.exe b/Redis-x64-5.0.14.1/redis-check-aof.exe new file mode 100644 index 0000000..5b1b425 Binary files /dev/null and b/Redis-x64-5.0.14.1/redis-check-aof.exe differ diff --git a/Redis-x64-5.0.14.1/redis-check-aof.pdb b/Redis-x64-5.0.14.1/redis-check-aof.pdb new file mode 100644 index 0000000..0d5726e Binary files /dev/null and b/Redis-x64-5.0.14.1/redis-check-aof.pdb differ diff --git a/Redis-x64-5.0.14.1/redis-check-rdb.exe b/Redis-x64-5.0.14.1/redis-check-rdb.exe new file mode 100644 index 0000000..5b1b425 Binary files /dev/null and b/Redis-x64-5.0.14.1/redis-check-rdb.exe differ diff --git a/Redis-x64-5.0.14.1/redis-check-rdb.pdb b/Redis-x64-5.0.14.1/redis-check-rdb.pdb new file mode 100644 index 0000000..0d5726e Binary files /dev/null and b/Redis-x64-5.0.14.1/redis-check-rdb.pdb differ diff --git a/Redis-x64-5.0.14.1/redis-cli.exe b/Redis-x64-5.0.14.1/redis-cli.exe new file mode 100644 index 0000000..40a73ba Binary files /dev/null and b/Redis-x64-5.0.14.1/redis-cli.exe differ diff --git a/Redis-x64-5.0.14.1/redis-cli.pdb b/Redis-x64-5.0.14.1/redis-cli.pdb new file mode 100644 index 0000000..121bae1 Binary files /dev/null and b/Redis-x64-5.0.14.1/redis-cli.pdb differ diff --git a/Redis-x64-5.0.14.1/redis-server.exe b/Redis-x64-5.0.14.1/redis-server.exe new file mode 100644 index 0000000..5b1b425 Binary files /dev/null and b/Redis-x64-5.0.14.1/redis-server.exe differ diff --git a/Redis-x64-5.0.14.1/redis-server.pdb b/Redis-x64-5.0.14.1/redis-server.pdb new file mode 100644 index 0000000..0d5726e Binary files /dev/null and b/Redis-x64-5.0.14.1/redis-server.pdb differ diff --git a/Redis-x64-5.0.14.1/redis.windows-service.conf b/Redis-x64-5.0.14.1/redis.windows-service.conf new file mode 100644 index 0000000..0b6b1da --- /dev/null +++ b/Redis-x64-5.0.14.1/redis.windows-service.conf @@ -0,0 +1,1336 @@ +# Redis configuration file example + +# Note on units: when memory size is needed, it is possible to specify +# it in the usual form of 1k 5GB 4M and so forth: +# +# 1k => 1000 bytes +# 1kb => 1024 bytes +# 1m => 1000000 bytes +# 1mb => 1024*1024 bytes +# 1g => 1000000000 bytes +# 1gb => 1024*1024*1024 bytes +# +# units are case insensitive so 1GB 1Gb 1gB are all the same. + +################################## INCLUDES ################################### + +# Include one or more other config files here. This is useful if you +# have a standard template that goes to all Redis servers but also need +# to customize a few per-server settings. Include files can include +# other files, so use this wisely. +# +# Notice option "include" won't be rewritten by command "CONFIG REWRITE" +# from admin or Redis Sentinel. Since Redis always uses the last processed +# line as value of a configuration directive, you'd better put includes +# at the beginning of this file to avoid overwriting config change at runtime. +# +# If instead you are interested in using includes to override configuration +# options, it is better to use include as the last line. +# +# include .\path\to\local.conf +# include c:\path\to\other.conf + +################################## MODULES ##################################### + +# Load modules at startup. If the server is not able to load modules +# it will abort. It is possible to use multiple loadmodule directives. +# +# loadmodule .\path\to\my_module.dll +# loadmodule c:\path\to\other_module.dll + +################################## NETWORK ##################################### + +# By default, if no "bind" configuration directive is specified, Redis listens +# for connections from all the network interfaces available on the server. +# It is possible to listen to just one or multiple selected interfaces using +# the "bind" configuration directive, followed by one or more IP addresses. +# +# Examples: +# +# bind 192.168.1.100 10.0.0.1 +# bind 127.0.0.1 ::1 +# +# ~~~ WARNING ~~~ If the computer running Redis is directly exposed to the +# internet, binding to all the interfaces is dangerous and will expose the +# instance to everybody on the internet. So by default we uncomment the +# following bind directive, that will force Redis to listen only into +# the IPv4 loopback interface address (this means Redis will be able to +# accept connections only from clients running into the same computer it +# is running). +# +# IF YOU ARE SURE YOU WANT YOUR INSTANCE TO LISTEN TO ALL THE INTERFACES +# JUST COMMENT THE FOLLOWING LINE. +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +bind 127.0.0.1 + +# Protected mode is a layer of security protection, in order to avoid that +# Redis instances left open on the internet are accessed and exploited. +# +# When protected mode is on and if: +# +# 1) The server is not binding explicitly to a set of addresses using the +# "bind" directive. +# 2) No password is configured. +# +# The server only accepts connections from clients connecting from the +# IPv4 and IPv6 loopback addresses 127.0.0.1 and ::1, and from Unix domain +# sockets. +# +# By default protected mode is enabled. You should disable it only if +# you are sure you want clients from other hosts to connect to Redis +# even if no authentication is configured, nor a specific set of interfaces +# are explicitly listed using the "bind" directive. +protected-mode yes + +# Accept connections on the specified port, default is 6379 (IANA #815344). +# If port 0 is specified Redis will not listen on a TCP socket. +port 6379 + +# TCP listen() backlog. +# +# In high requests-per-second environments you need an high backlog in order +# to avoid slow clients connections issues. Note that the Linux kernel +# will silently truncate it to the value of /proc/sys/net/core/somaxconn so +# make sure to raise both the value of somaxconn and tcp_max_syn_backlog +# in order to get the desired effect. +tcp-backlog 511 + +# Unix socket. +# +# Specify the path for the Unix socket that will be used to listen for +# incoming connections. There is no default, so Redis will not listen +# on a unix socket when not specified. +# +# unixsocket /tmp/redis.sock +# unixsocketperm 700 + +# Close the connection after a client is idle for N seconds (0 to disable) +timeout 0 + +# TCP keepalive. +# +# If non-zero, use SO_KEEPALIVE to send TCP ACKs to clients in absence +# of communication. This is useful for two reasons: +# +# 1) Detect dead peers. +# 2) Take the connection alive from the point of view of network +# equipment in the middle. +# +# On Linux, the specified value (in seconds) is the period used to send ACKs. +# Note that to close the connection the double of the time is needed. +# On other kernels the period depends on the kernel configuration. +# +# A reasonable value for this option is 300 seconds, which is the new +# Redis default starting with Redis 3.2.1. +tcp-keepalive 300 + +################################# GENERAL ##################################### + +# By default Redis does not run as a daemon. Use 'yes' if you need it. +# Note that Redis will write a pid file in /var/run/redis.pid when daemonized. +# NOT SUPPORTED ON WINDOWS daemonize no + +# If you run Redis from upstart or systemd, Redis can interact with your +# supervision tree. Options: +# supervised no - no supervision interaction +# supervised upstart - signal upstart by putting Redis into SIGSTOP mode +# supervised systemd - signal systemd by writing READY=1 to $NOTIFY_SOCKET +# supervised auto - detect upstart or systemd method based on +# UPSTART_JOB or NOTIFY_SOCKET environment variables +# Note: these supervision methods only signal "process is ready." +# They do not enable continuous liveness pings back to your supervisor. +# NOT SUPPORTED ON WINDOWS supervised no + +# If a pid file is specified, Redis writes it where specified at startup +# and removes it at exit. +# +# When the server runs non daemonized, no pid file is created if none is +# specified in the configuration. When the server is daemonized, the pid file +# is used even if not specified, defaulting to "/var/run/redis.pid". +# +# Creating a pid file is best effort: if Redis is not able to create it +# nothing bad happens, the server will start and run normally. +# NOT SUPPORTED ON WINDOWS pidfile /var/run/redis.pid + +# Specify the server verbosity level. +# This can be one of: +# debug (a lot of information, useful for development/testing) +# verbose (many rarely useful info, but not a mess like the debug level) +# notice (moderately verbose, what you want in production probably) +# warning (only very important / critical messages are logged) +loglevel notice + +# Specify the log file name. Also 'stdout' can be used to force +# Redis to log on the standard output. +logfile "server_log.txt" + +# To enable logging to the Windows EventLog, just set 'syslog-enabled' to +# yes, and optionally update the other syslog parameters to suit your needs. +# If Redis is installed and launched as a Windows Service, this will +# automatically be enabled. +syslog-enabled yes + +# Specify the source name of the events in the Windows Application log. +syslog-ident redis + +# Specify the syslog facility. Must be USER or between LOCAL0-LOCAL7. +# NOT SUPPORTED ON WINDOWS syslog-facility local0 + +# Set the number of databases. The default database is DB 0, you can select +# a different one on a per-connection basis using SELECT where +# dbid is a number between 0 and 'databases'-1 +databases 16 + +# By default Redis shows an ASCII art logo only when started to log to the +# standard output and if the standard output is a TTY. Basically this means +# that normally a logo is displayed only in interactive sessions. +# +# However it is possible to force the pre-4.0 behavior and always show a +# ASCII art logo in startup logs by setting the following option to yes. +always-show-logo yes + +################################ SNAPSHOTTING ################################ +# +# Save the DB on disk: +# +# save +# +# Will save the DB if both the given number of seconds and the given +# number of write operations against the DB occurred. +# +# In the example below the behaviour will be to save: +# after 900 sec (15 min) if at least 1 key changed +# after 300 sec (5 min) if at least 10 keys changed +# after 60 sec if at least 10000 keys changed +# +# Note: you can disable saving completely by commenting out all "save" lines. +# +# It is also possible to remove all the previously configured save +# points by adding a save directive with a single empty string argument +# like in the following example: +# +# save "" + +save 900 1 +save 300 10 +save 60 10000 + +# By default Redis will stop accepting writes if RDB snapshots are enabled +# (at least one save point) and the latest background save failed. +# This will make the user aware (in a hard way) that data is not persisting +# on disk properly, otherwise chances are that no one will notice and some +# disaster will happen. +# +# If the background saving process will start working again Redis will +# automatically allow writes again. +# +# However if you have setup your proper monitoring of the Redis server +# and persistence, you may want to disable this feature so that Redis will +# continue to work as usual even if there are problems with disk, +# permissions, and so forth. +stop-writes-on-bgsave-error yes + +# Compress string objects using LZF when dump .rdb databases? +# For default that's set to 'yes' as it's almost always a win. +# If you want to save some CPU in the saving child set it to 'no' but +# the dataset will likely be bigger if you have compressible values or keys. +rdbcompression yes + +# Since version 5 of RDB a CRC64 checksum is placed at the end of the file. +# This makes the format more resistant to corruption but there is a performance +# hit to pay (around 10%) when saving and loading RDB files, so you can disable it +# for maximum performances. +# +# RDB files created with checksum disabled have a checksum of zero that will +# tell the loading code to skip the check. +rdbchecksum yes + +# The filename where to dump the DB +dbfilename dump.rdb + +# The working directory. +# +# The DB will be written inside this directory, with the filename specified +# above using the 'dbfilename' configuration directive. +# +# The Append Only File will also be created inside this directory. +# +# Note that you must specify a directory here, not a file name. +dir ./ + +################################# REPLICATION ################################# + +# Master-Replica replication. Use replicaof to make a Redis instance a copy of +# another Redis server. A few things to understand ASAP about Redis replication. +# +# +------------------+ +---------------+ +# | Master | ---> | Replica | +# | (receive writes) | | (exact copy) | +# +------------------+ +---------------+ +# +# 1) Redis replication is asynchronous, but you can configure a master to +# stop accepting writes if it appears to be not connected with at least +# a given number of replicas. +# 2) Redis replicas are able to perform a partial resynchronization with the +# master if the replication link is lost for a relatively small amount of +# time. You may want to configure the replication backlog size (see the next +# sections of this file) with a sensible value depending on your needs. +# 3) Replication is automatic and does not need user intervention. After a +# network partition replicas automatically try to reconnect to masters +# and resynchronize with them. +# +# replicaof + +# If the master is password protected (using the "requirepass" configuration +# directive below) it is possible to tell the replica to authenticate before +# starting the replication synchronization process, otherwise the master will +# refuse the replica request. +# +# masterauth + +# When a replica loses its connection with the master, or when the replication +# is still in progress, the replica can act in two different ways: +# +# 1) if replica-serve-stale-data is set to 'yes' (the default) the replica will +# still reply to client requests, possibly with out of date data, or the +# data set may just be empty if this is the first synchronization. +# +# 2) if replica-serve-stale-data is set to 'no' the replica will reply with +# an error "SYNC with master in progress" to all the kind of commands +# but to INFO, replicaOF, AUTH, PING, SHUTDOWN, REPLCONF, ROLE, CONFIG, +# SUBSCRIBE, UNSUBSCRIBE, PSUBSCRIBE, PUNSUBSCRIBE, PUBLISH, PUBSUB, +# COMMAND, POST, HOST: and LATENCY. +# +replica-serve-stale-data yes + +# You can configure a replica instance to accept writes or not. Writing against +# a replica instance may be useful to store some ephemeral data (because data +# written on a replica will be easily deleted after resync with the master) but +# may also cause problems if clients are writing to it because of a +# misconfiguration. +# +# Since Redis 2.6 by default replicas are read-only. +# +# Note: read only replicas are not designed to be exposed to untrusted clients +# on the internet. It's just a protection layer against misuse of the instance. +# Still a read only replica exports by default all the administrative commands +# such as CONFIG, DEBUG, and so forth. To a limited extent you can improve +# security of read only replicas using 'rename-command' to shadow all the +# administrative / dangerous commands. +replica-read-only yes + +# Replication SYNC strategy: disk or socket. +# +# ------------------------------------------------------- +# WARNING: DISKLESS REPLICATION IS EXPERIMENTAL CURRENTLY +# ------------------------------------------------------- +# +# New replicas and reconnecting replicas that are not able to continue the replication +# process just receiving differences, need to do what is called a "full +# synchronization". An RDB file is transmitted from the master to the replicas. +# The transmission can happen in two different ways: +# +# 1) Disk-backed: The Redis master creates a new process that writes the RDB +# file on disk. Later the file is transferred by the parent +# process to the replicas incrementally. +# 2) Diskless: The Redis master creates a new process that directly writes the +# RDB file to replica sockets, without touching the disk at all. +# +# With disk-backed replication, while the RDB file is generated, more replicas +# can be queued and served with the RDB file as soon as the current child producing +# the RDB file finishes its work. With diskless replication instead once +# the transfer starts, new replicas arriving will be queued and a new transfer +# will start when the current one terminates. +# +# When diskless replication is used, the master waits a configurable amount of +# time (in seconds) before starting the transfer in the hope that multiple replicas +# will arrive and the transfer can be parallelized. +# +# With slow disks and fast (large bandwidth) networks, diskless replication +# works better. +repl-diskless-sync no + +# When diskless replication is enabled, it is possible to configure the delay +# the server waits in order to spawn the child that transfers the RDB via socket +# to the replicas. +# +# This is important since once the transfer starts, it is not possible to serve +# new replicas arriving, that will be queued for the next RDB transfer, so the server +# waits a delay in order to let more replicas arrive. +# +# The delay is specified in seconds, and by default is 5 seconds. To disable +# it entirely just set it to 0 seconds and the transfer will start ASAP. +repl-diskless-sync-delay 5 + +# Replicas send PINGs to server in a predefined interval. It's possible to change +# this interval with the repl_ping_replica_period option. The default value is 10 +# seconds. +# +# repl-ping-replica-period 10 + +# The following option sets the replication timeout for: +# +# 1) Bulk transfer I/O during SYNC, from the point of view of replica. +# 2) Master timeout from the point of view of replicas (data, pings). +# 3) Replica timeout from the point of view of masters (REPLCONF ACK pings). +# +# It is important to make sure that this value is greater than the value +# specified for repl-ping-replica-period otherwise a timeout will be detected +# every time there is low traffic between the master and the replica. +# +# repl-timeout 60 + +# Disable TCP_NODELAY on the replica socket after SYNC? +# +# If you select "yes" Redis will use a smaller number of TCP packets and +# less bandwidth to send data to replicas. But this can add a delay for +# the data to appear on the replica side, up to 40 milliseconds with +# Linux kernels using a default configuration. +# +# If you select "no" the delay for data to appear on the replica side will +# be reduced but more bandwidth will be used for replication. +# +# By default we optimize for low latency, but in very high traffic conditions +# or when the master and replicas are many hops away, turning this to "yes" may +# be a good idea. +repl-disable-tcp-nodelay no + +# Set the replication backlog size. The backlog is a buffer that accumulates +# replica data when replicas are disconnected for some time, so that when a replica +# wants to reconnect again, often a full resync is not needed, but a partial +# resync is enough, just passing the portion of data the replica missed while +# disconnected. +# +# The bigger the replication backlog, the longer the time the replica can be +# disconnected and later be able to perform a partial resynchronization. +# +# The backlog is only allocated once there is at least a replica connected. +# +# repl-backlog-size 1mb + +# After a master has no longer connected replicas for some time, the backlog +# will be freed. The following option configures the amount of seconds that +# need to elapse, starting from the time the last replica disconnected, for +# the backlog buffer to be freed. +# +# Note that replicas never free the backlog for timeout, since they may be +# promoted to masters later, and should be able to correctly "partially +# resynchronize" with the replicas: hence they should always accumulate backlog. +# +# A value of 0 means to never release the backlog. +# +# repl-backlog-ttl 3600 + +# The replica priority is an integer number published by Redis in the INFO output. +# It is used by Redis Sentinel in order to select a replica to promote into a +# master if the master is no longer working correctly. +# +# A replica with a low priority number is considered better for promotion, so +# for instance if there are three replicas with priority 10, 100, 25 Sentinel will +# pick the one with priority 10, that is the lowest. +# +# However a special priority of 0 marks the replica as not able to perform the +# role of master, so a replica with priority of 0 will never be selected by +# Redis Sentinel for promotion. +# +# By default the priority is 100. +replica-priority 100 + +# It is possible for a master to stop accepting writes if there are less than +# N replicas connected, having a lag less or equal than M seconds. +# +# The N replicas need to be in "online" state. +# +# The lag in seconds, that must be <= the specified value, is calculated from +# the last ping received from the replica, that is usually sent every second. +# +# This option does not GUARANTEE that N replicas will accept the write, but +# will limit the window of exposure for lost writes in case not enough replicas +# are available, to the specified number of seconds. +# +# For example to require at least 3 replicas with a lag <= 10 seconds use: +# +# min-replicas-to-write 3 +# min-replicas-max-lag 10 +# +# Setting one or the other to 0 disables the feature. +# +# By default min-replicas-to-write is set to 0 (feature disabled) and +# min-replicas-max-lag is set to 10. + +# A Redis master is able to list the address and port of the attached +# replicas in different ways. For example the "INFO replication" section +# offers this information, which is used, among other tools, by +# Redis Sentinel in order to discover replica instances. +# Another place where this info is available is in the output of the +# "ROLE" command of a master. +# +# The listed IP and address normally reported by a replica is obtained +# in the following way: +# +# IP: The address is auto detected by checking the peer address +# of the socket used by the replica to connect with the master. +# +# Port: The port is communicated by the replica during the replication +# handshake, and is normally the port that the replica is using to +# listen for connections. +# +# However when port forwarding or Network Address Translation (NAT) is +# used, the replica may be actually reachable via different IP and port +# pairs. The following two options can be used by a replica in order to +# report to its master a specific set of IP and port, so that both INFO +# and ROLE will report those values. +# +# There is no need to use both the options if you need to override just +# the port or the IP address. +# +# replica-announce-ip 5.5.5.5 +# replica-announce-port 1234 + +################################## SECURITY ################################### + +# Require clients to issue AUTH before processing any other +# commands. This might be useful in environments in which you do not trust +# others with access to the host running redis-server. +# +# This should stay commented out for backward compatibility and because most +# people do not need auth (e.g. they run their own servers). +# +# Warning: since Redis is pretty fast an outside user can try up to +# 150k passwords per second against a good box. This means that you should +# use a very strong password otherwise it will be very easy to break. +# +# requirepass foobared + +# Command renaming. +# +# It is possible to change the name of dangerous commands in a shared +# environment. For instance the CONFIG command may be renamed into something +# hard to guess so that it will still be available for internal-use tools +# but not available for general clients. +# +# Example: +# +# rename-command CONFIG b840fc02d524045429941cc15f59e41cb7be6c52 +# +# It is also possible to completely kill a command by renaming it into +# an empty string: +# +# rename-command CONFIG "" +# +# Please note that changing the name of commands that are logged into the +# AOF file or transmitted to replicas may cause problems. + +################################### CLIENTS #################################### + +# Set the max number of connected clients at the same time. By default +# this limit is set to 10000 clients, however if the Redis server is not +# able to configure the process file limit to allow for the specified limit +# the max number of allowed clients is set to the current file limit +# minus 32 (as Redis reserves a few file descriptors for internal uses). +# +# Once the limit is reached Redis will close all the new connections sending +# an error 'max number of clients reached'. +# +# maxclients 10000 + +############################## MEMORY MANAGEMENT ################################ + +# If Redis is to be used as an in-memory-only cache without any kind of +# persistence, then the fork() mechanism used by the background AOF/RDB +# persistence is unnecessary. As an optimization, all persistence can be +# turned off in the Windows version of Redis. This will redirect heap +# allocations to the system heap allocator, and disable commands that would +# otherwise cause fork() operations: BGSAVE and BGREWRITEAOF. +# This flag may not be combined with any of the other flags that configure +# AOF and RDB operations. +# persistence-available [(yes)|no] + +# Set a memory usage limit to the specified amount of bytes. +# When the memory limit is reached Redis will try to remove keys +# according to the eviction policy selected (see maxmemory-policy). +# +# If Redis can't remove keys according to the policy, or if the policy is +# set to 'noeviction', Redis will start to reply with errors to commands +# that would use more memory, like SET, LPUSH, and so on, and will continue +# to reply to read-only commands like GET. +# +# This option is usually useful when using Redis as an LRU or LFU cache, or to +# set a hard memory limit for an instance (using the 'noeviction' policy). +# +# WARNING: If you have replicas attached to an instance with maxmemory on, +# the size of the output buffers needed to feed the replicas are subtracted +# from the used memory count, so that network problems / resyncs will +# not trigger a loop where keys are evicted, and in turn the output +# buffer of replicas is full with DELs of keys evicted triggering the deletion +# of more keys, and so forth until the database is completely emptied. +# +# In short... if you have replicas attached it is suggested that you set a lower +# limit for maxmemory so that there is some free RAM on the system for replica +# output buffers (but this is not needed if the policy is 'noeviction'). +# +# WARNING: not setting maxmemory will cause Redis to terminate with an +# out-of-memory exception if the heap limit is reached. +# +# NOTE: since Redis uses the system paging file to allocate the heap memory, +# the Working Set memory usage showed by the Windows Task Manager or by other +# tools such as ProcessExplorer will not always be accurate. For example, right +# after a background save of the RDB or the AOF files, the working set value +# may drop significantly. In order to check the correct amount of memory used +# by the redis-server to store the data, use the INFO client command. The INFO +# command shows only the memory used to store the redis data, not the extra +# memory used by the Windows process for its own requirements. Th3 extra amount +# of memory not reported by the INFO command can be calculated subtracting the +# Peak Working Set reported by the Windows Task Manager and the used_memory_peak +# reported by the INFO command. +# +# maxmemory + +# MAXMEMORY POLICY: how Redis will select what to remove when maxmemory +# is reached. You can select among five behaviors: +# +# volatile-lru -> Evict using approximated LRU among the keys with an expire set. +# allkeys-lru -> Evict any key using approximated LRU. +# volatile-lfu -> Evict using approximated LFU among the keys with an expire set. +# allkeys-lfu -> Evict any key using approximated LFU. +# volatile-random -> Remove a random key among the ones with an expire set. +# allkeys-random -> Remove a random key, any key. +# volatile-ttl -> Remove the key with the nearest expire time (minor TTL) +# noeviction -> Don't evict anything, just return an error on write operations. +# +# LRU means Least Recently Used +# LFU means Least Frequently Used +# +# Both LRU, LFU and volatile-ttl are implemented using approximated +# randomized algorithms. +# +# Note: with any of the above policies, Redis will return an error on write +# operations, when there are no suitable keys for eviction. +# +# At the date of writing these commands are: set setnx setex append +# incr decr rpush lpush rpushx lpushx linsert lset rpoplpush sadd +# sinter sinterstore sunion sunionstore sdiff sdiffstore zadd zincrby +# zunionstore zinterstore hset hsetnx hmset hincrby incrby decrby +# getset mset msetnx exec sort +# +# The default is: +# +# maxmemory-policy noeviction + +# LRU, LFU and minimal TTL algorithms are not precise algorithms but approximated +# algorithms (in order to save memory), so you can tune it for speed or +# accuracy. For default Redis will check five keys and pick the one that was +# used less recently, you can change the sample size using the following +# configuration directive. +# +# The default of 5 produces good enough results. 10 Approximates very closely +# true LRU but costs more CPU. 3 is faster but not very accurate. +# +# maxmemory-samples 5 + +# Starting from Redis 5, by default a replica will ignore its maxmemory setting +# (unless it is promoted to master after a failover or manually). It means +# that the eviction of keys will be just handled by the master, sending the +# DEL commands to the replica as keys evict in the master side. +# +# This behavior ensures that masters and replicas stay consistent, and is usually +# what you want, however if your replica is writable, or you want the replica to have +# a different memory setting, and you are sure all the writes performed to the +# replica are idempotent, then you may change this default (but be sure to understand +# what you are doing). +# +# Note that since the replica by default does not evict, it may end using more +# memory than the one set via maxmemory (there are certain buffers that may +# be larger on the replica, or data structures may sometimes take more memory and so +# forth). So make sure you monitor your replicas and make sure they have enough +# memory to never hit a real out-of-memory condition before the master hits +# the configured maxmemory setting. +# +# replica-ignore-maxmemory yes + +############################# LAZY FREEING #################################### + +# Redis has two primitives to delete keys. One is called DEL and is a blocking +# deletion of the object. It means that the server stops processing new commands +# in order to reclaim all the memory associated with an object in a synchronous +# way. If the key deleted is associated with a small object, the time needed +# in order to execute the DEL command is very small and comparable to most other +# O(1) or O(log_N) commands in Redis. However if the key is associated with an +# aggregated value containing millions of elements, the server can block for +# a long time (even seconds) in order to complete the operation. +# +# For the above reasons Redis also offers non blocking deletion primitives +# such as UNLINK (non blocking DEL) and the ASYNC option of FLUSHALL and +# FLUSHDB commands, in order to reclaim memory in background. Those commands +# are executed in constant time. Another thread will incrementally free the +# object in the background as fast as possible. +# +# DEL, UNLINK and ASYNC option of FLUSHALL and FLUSHDB are user-controlled. +# It's up to the design of the application to understand when it is a good +# idea to use one or the other. However the Redis server sometimes has to +# delete keys or flush the whole database as a side effect of other operations. +# Specifically Redis deletes objects independently of a user call in the +# following scenarios: +# +# 1) On eviction, because of the maxmemory and maxmemory policy configurations, +# in order to make room for new data, without going over the specified +# memory limit. +# 2) Because of expire: when a key with an associated time to live (see the +# EXPIRE command) must be deleted from memory. +# 3) Because of a side effect of a command that stores data on a key that may +# already exist. For example the RENAME command may delete the old key +# content when it is replaced with another one. Similarly SUNIONSTORE +# or SORT with STORE option may delete existing keys. The SET command +# itself removes any old content of the specified key in order to replace +# it with the specified string. +# 4) During replication, when a replica performs a full resynchronization with +# its master, the content of the whole database is removed in order to +# load the RDB file just transferred. +# +# In all the above cases the default is to delete objects in a blocking way, +# like if DEL was called. However you can configure each case specifically +# in order to instead release memory in a non-blocking way like if UNLINK +# was called, using the following configuration directives: + +lazyfree-lazy-eviction no +lazyfree-lazy-expire no +lazyfree-lazy-server-del no +replica-lazy-flush no + +############################## APPEND ONLY MODE ############################### + +# By default Redis asynchronously dumps the dataset on disk. This mode is +# good enough in many applications, but an issue with the Redis process or +# a power outage may result into a few minutes of writes lost (depending on +# the configured save points). +# +# The Append Only File is an alternative persistence mode that provides +# much better durability. For instance using the default data fsync policy +# (see later in the config file) Redis can lose just one second of writes in a +# dramatic event like a server power outage, or a single write if something +# wrong with the Redis process itself happens, but the operating system is +# still running correctly. +# +# AOF and RDB persistence can be enabled at the same time without problems. +# If the AOF is enabled on startup Redis will load the AOF, that is the file +# with the better durability guarantees. +# +# Please check http://redis.io/topics/persistence for more information. + +appendonly no + +# The name of the append only file (default: "appendonly.aof") + +appendfilename "appendonly.aof" + +# The fsync() call tells the Operating System to actually write data on disk +# instead of waiting for more data in the output buffer. Some OS will really flush +# data on disk, some other OS will just try to do it ASAP. +# +# Redis supports three different modes: +# +# no: don't fsync, just let the OS flush the data when it wants. Faster. +# always: fsync after every write to the append only log. Slow, Safest. +# everysec: fsync only one time every second. Compromise. +# +# The default is "everysec", as that's usually the right compromise between +# speed and data safety. It's up to you to understand if you can relax this to +# "no" that will let the operating system flush the output buffer when +# it wants, for better performances (but if you can live with the idea of +# some data loss consider the default persistence mode that's snapshotting), +# or on the contrary, use "always" that's very slow but a bit safer than +# everysec. +# +# More details please check the following article: +# http://antirez.com/post/redis-persistence-demystified.html +# +# If unsure, use "everysec". + +# appendfsync always +appendfsync everysec +# appendfsync no + +# When the AOF fsync policy is set to always or everysec, and a background +# saving process (a background save or AOF log background rewriting) is +# performing a lot of I/O against the disk, in some Linux configurations +# Redis may block too long on the fsync() call. Note that there is no fix for +# this currently, as even performing fsync in a different thread will block +# our synchronous write(2) call. +# +# In order to mitigate this problem it's possible to use the following option +# that will prevent fsync() from being called in the main process while a +# BGSAVE or BGREWRITEAOF is in progress. +# +# This means that while another child is saving, the durability of Redis is +# the same as "appendfsync none". In practical terms, this means that it is +# possible to lose up to 30 seconds of log in the worst scenario (with the +# default Linux settings). +# +# If you have latency problems turn this to "yes". Otherwise leave it as +# "no" that is the safest pick from the point of view of durability. + +no-appendfsync-on-rewrite no + +# Automatic rewrite of the append only file. +# Redis is able to automatically rewrite the log file implicitly calling +# BGREWRITEAOF when the AOF log size grows by the specified percentage. +# +# This is how it works: Redis remembers the size of the AOF file after the +# latest rewrite (if no rewrite has happened since the restart, the size of +# the AOF at startup is used). +# +# This base size is compared to the current size. If the current size is +# bigger than the specified percentage, the rewrite is triggered. Also +# you need to specify a minimal size for the AOF file to be rewritten, this +# is useful to avoid rewriting the AOF file even if the percentage increase +# is reached but it is still pretty small. +# +# Specify a percentage of zero in order to disable the automatic AOF +# rewrite feature. + +auto-aof-rewrite-percentage 100 +auto-aof-rewrite-min-size 64mb + +# An AOF file may be found to be truncated at the end during the Redis +# startup process, when the AOF data gets loaded back into memory. +# This may happen when the system where Redis is running +# crashes, especially when an ext4 filesystem is mounted without the +# data=ordered option (however this can't happen when Redis itself +# crashes or aborts but the operating system still works correctly). +# +# Redis can either exit with an error when this happens, or load as much +# data as possible (the default now) and start if the AOF file is found +# to be truncated at the end. The following option controls this behavior. +# +# If aof-load-truncated is set to yes, a truncated AOF file is loaded and +# the Redis server starts emitting a log to inform the user of the event. +# Otherwise if the option is set to no, the server aborts with an error +# and refuses to start. When the option is set to no, the user requires +# to fix the AOF file using the "redis-check-aof" utility before to restart +# the server. +# +# Note that if the AOF file will be found to be corrupted in the middle +# the server will still exit with an error. This option only applies when +# Redis will try to read more data from the AOF file but not enough bytes +# will be found. +aof-load-truncated yes + +# When rewriting the AOF file, Redis is able to use an RDB preamble in the +# AOF file for faster rewrites and recoveries. When this option is turned +# on the rewritten AOF file is composed of two different stanzas: +# +# [RDB file][AOF tail] +# +# When loading Redis recognizes that the AOF file starts with the "REDIS" +# string and loads the prefixed RDB file, and continues loading the AOF +# tail. +aof-use-rdb-preamble yes + +################################ LUA SCRIPTING ############################### + +# Max execution time of a Lua script in milliseconds. +# +# If the maximum execution time is reached Redis will log that a script is +# still in execution after the maximum allowed time and will start to +# reply to queries with an error. +# +# When a long running script exceeds the maximum execution time only the +# SCRIPT KILL and SHUTDOWN NOSAVE commands are available. The first can be +# used to stop a script that did not yet called write commands. The second +# is the only way to shut down the server in the case a write command was +# already issued by the script but the user doesn't want to wait for the natural +# termination of the script. +# +# Set it to 0 or a negative value for unlimited execution without warnings. +lua-time-limit 5000 + +################################ REDIS CLUSTER ############################### + +# Normal Redis instances can't be part of a Redis Cluster; only nodes that are +# started as cluster nodes can. In order to start a Redis instance as a +# cluster node enable the cluster support uncommenting the following: +# +# cluster-enabled yes + +# Every cluster node has a cluster configuration file. This file is not +# intended to be edited by hand. It is created and updated by Redis nodes. +# Every Redis Cluster node requires a different cluster configuration file. +# Make sure that instances running in the same system do not have +# overlapping cluster configuration file names. +# +# cluster-config-file nodes-6379.conf + +# Cluster node timeout is the amount of milliseconds a node must be unreachable +# for it to be considered in failure state. +# Most other internal time limits are multiple of the node timeout. +# +# cluster-node-timeout 15000 + +# A replica of a failing master will avoid to start a failover if its data +# looks too old. +# +# There is no simple way for a replica to actually have an exact measure of +# its "data age", so the following two checks are performed: +# +# 1) If there are multiple replicas able to failover, they exchange messages +# in order to try to give an advantage to the replica with the best +# replication offset (more data from the master processed). +# Replicas will try to get their rank by offset, and apply to the start +# of the failover a delay proportional to their rank. +# +# 2) Every single replica computes the time of the last interaction with +# its master. This can be the last ping or command received (if the master +# is still in the "connected" state), or the time that elapsed since the +# disconnection with the master (if the replication link is currently down). +# If the last interaction is too old, the replica will not try to failover +# at all. +# +# The point "2" can be tuned by user. Specifically a replica will not perform +# the failover if, since the last interaction with the master, the time +# elapsed is greater than: +# +# (node-timeout * replica-validity-factor) + repl-ping-replica-period +# +# So for example if node-timeout is 30 seconds, and the replica-validity-factor +# is 10, and assuming a default repl-ping-replica-period of 10 seconds, the +# replica will not try to failover if it was not able to talk with the master +# for longer than 310 seconds. +# +# A large replica-validity-factor may allow replicas with too old data to failover +# a master, while a too small value may prevent the cluster from being able to +# elect a replica at all. +# +# For maximum availability, it is possible to set the replica-validity-factor +# to a value of 0, which means, that replicas will always try to failover the +# master regardless of the last time they interacted with the master. +# (However they'll always try to apply a delay proportional to their +# offset rank). +# +# Zero is the only value able to guarantee that when all the partitions heal +# the cluster will always be able to continue. +# +# cluster-replica-validity-factor 10 + +# Cluster replicas are able to migrate to orphaned masters, that are masters +# that are left without working replicas. This improves the cluster ability +# to resist to failures as otherwise an orphaned master can't be failed over +# in case of failure if it has no working replicas. +# +# Replicas migrate to orphaned masters only if there are still at least a +# given number of other working replicas for their old master. This number +# is the "migration barrier". A migration barrier of 1 means that a replica +# will migrate only if there is at least 1 other working replica for its master +# and so forth. It usually reflects the number of replicas you want for every +# master in your cluster. +# +# Default is 1 (replicas migrate only if their masters remain with at least +# one replica). To disable migration just set it to a very large value. +# A value of 0 can be set but is useful only for debugging and dangerous +# in production. +# +# cluster-migration-barrier 1 + +# By default Redis Cluster nodes stop accepting queries if they detect there +# is at least an hash slot uncovered (no available node is serving it). +# This way if the cluster is partially down (for example a range of hash slots +# are no longer covered) all the cluster becomes, eventually, unavailable. +# It automatically returns available as soon as all the slots are covered again. +# +# However sometimes you want the subset of the cluster which is working, +# to continue to accept queries for the part of the key space that is still +# covered. In order to do so, just set the cluster-require-full-coverage +# option to no. +# +# cluster-require-full-coverage yes + +# This option, when set to yes, prevents replicas from trying to failover its +# master during master failures. However the master can still perform a +# manual failover, if forced to do so. +# +# This is useful in different scenarios, especially in the case of multiple +# data center operations, where we want one side to never be promoted if not +# in the case of a total DC failure. +# +# cluster-replica-no-failover no + +# In order to setup your cluster make sure to read the documentation +# available at http://redis.io web site. + +########################## CLUSTER DOCKER/NAT support ######################## + +# In certain deployments, Redis Cluster nodes address discovery fails, because +# addresses are NAT-ted or because ports are forwarded (the typical case is +# Docker and other containers). +# +# In order to make Redis Cluster working in such environments, a static +# configuration where each node knows its public address is needed. The +# following two options are used for this scope, and are: +# +# * cluster-announce-ip +# * cluster-announce-port +# * cluster-announce-bus-port +# +# Each instruct the node about its address, client port, and cluster message +# bus port. The information is then published in the header of the bus packets +# so that other nodes will be able to correctly map the address of the node +# publishing the information. +# +# If the above options are not used, the normal Redis Cluster auto-detection +# will be used instead. +# +# Note that when remapped, the bus port may not be at the fixed offset of +# clients port + 10000, so you can specify any port and bus-port depending +# on how they get remapped. If the bus-port is not set, a fixed offset of +# 10000 will be used as usually. +# +# Example: +# +# cluster-announce-ip 10.1.1.5 +# cluster-announce-port 6379 +# cluster-announce-bus-port 6380 + +################################## SLOW LOG ################################### + +# The Redis Slow Log is a system to log queries that exceeded a specified +# execution time. The execution time does not include the I/O operations +# like talking with the client, sending the reply and so forth, +# but just the time needed to actually execute the command (this is the only +# stage of command execution where the thread is blocked and can not serve +# other requests in the meantime). +# +# You can configure the slow log with two parameters: one tells Redis +# what is the execution time, in microseconds, to exceed in order for the +# command to get logged, and the other parameter is the length of the +# slow log. When a new command is logged the oldest one is removed from the +# queue of logged commands. + +# The following time is expressed in microseconds, so 1000000 is equivalent +# to one second. Note that a negative number disables the slow log, while +# a value of zero forces the logging of every command. +slowlog-log-slower-than 10000 + +# There is no limit to this length. Just be aware that it will consume memory. +# You can reclaim memory used by the slow log with SLOWLOG RESET. +slowlog-max-len 128 + +################################ LATENCY MONITOR ############################## + +# The Redis latency monitoring subsystem samples different operations +# at runtime in order to collect data related to possible sources of +# latency of a Redis instance. +# +# Via the LATENCY command this information is available to the user that can +# print graphs and obtain reports. +# +# The system only logs operations that were performed in a time equal or +# greater than the amount of milliseconds specified via the +# latency-monitor-threshold configuration directive. When its value is set +# to zero, the latency monitor is turned off. +# +# By default latency monitoring is disabled since it is mostly not needed +# if you don't have latency issues, and collecting data has a performance +# impact, that while very small, can be measured under big load. Latency +# monitoring can easily be enabled at runtime using the command +# "CONFIG SET latency-monitor-threshold " if needed. +latency-monitor-threshold 0 + +############################# EVENT NOTIFICATION ############################## + +# Redis can notify Pub/Sub clients about events happening in the key space. +# This feature is documented at http://redis.io/topics/notifications +# +# For instance if keyspace events notification is enabled, and a client +# performs a DEL operation on key "foo" stored in the Database 0, two +# messages will be published via Pub/Sub: +# +# PUBLISH __keyspace@0__:foo del +# PUBLISH __keyevent@0__:del foo +# +# It is possible to select the events that Redis will notify among a set +# of classes. Every class is identified by a single character: +# +# K Keyspace events, published with __keyspace@__ prefix. +# E Keyevent events, published with __keyevent@__ prefix. +# g Generic commands (non-type specific) like DEL, EXPIRE, RENAME, ... +# $ String commands +# l List commands +# s Set commands +# h Hash commands +# z Sorted set commands +# x Expired events (events generated every time a key expires) +# e Evicted events (events generated when a key is evicted for maxmemory) +# A Alias for g$lshzxe, so that the "AKE" string means all the events. +# +# The "notify-keyspace-events" takes as argument a string that is composed +# of zero or multiple characters. The empty string means that notifications +# are disabled. +# +# Example: to enable list and generic events, from the point of view of the +# event name, use: +# +# notify-keyspace-events Elg +# +# Example 2: to get the stream of the expired keys subscribing to channel +# name __keyevent@0__:expired use: +# +# notify-keyspace-events Ex +# +# By default all notifications are disabled because most users don't need +# this feature and the feature has some overhead. Note that if you don't +# specify at least one of K or E, no events will be delivered. +notify-keyspace-events "" + +############################### ADVANCED CONFIG ############################### + +# Hashes are encoded using a memory efficient data structure when they have a +# small number of entries, and the biggest entry does not exceed a given +# threshold. These thresholds can be configured using the following directives. +hash-max-ziplist-entries 512 +hash-max-ziplist-value 64 + +# Lists are also encoded in a special way to save a lot of space. +# The number of entries allowed per internal list node can be specified +# as a fixed maximum size or a maximum number of elements. +# For a fixed maximum size, use -5 through -1, meaning: +# -5: max size: 64 Kb <-- not recommended for normal workloads +# -4: max size: 32 Kb <-- not recommended +# -3: max size: 16 Kb <-- probably not recommended +# -2: max size: 8 Kb <-- good +# -1: max size: 4 Kb <-- good +# Positive numbers mean store up to _exactly_ that number of elements +# per list node. +# The highest performing option is usually -2 (8 Kb size) or -1 (4 Kb size), +# but if your use case is unique, adjust the settings as necessary. +list-max-ziplist-size -2 + +# Lists may also be compressed. +# Compress depth is the number of quicklist ziplist nodes from *each* side of +# the list to *exclude* from compression. The head and tail of the list +# are always uncompressed for fast push/pop operations. Settings are: +# 0: disable all list compression +# 1: depth 1 means "don't start compressing until after 1 node into the list, +# going from either the head or tail" +# So: [head]->node->node->...->node->[tail] +# [head], [tail] will always be uncompressed; inner nodes will compress. +# 2: [head]->[next]->node->node->...->node->[prev]->[tail] +# 2 here means: don't compress head or head->next or tail->prev or tail, +# but compress all nodes between them. +# 3: [head]->[next]->[next]->node->node->...->node->[prev]->[prev]->[tail] +# etc. +list-compress-depth 0 + +# Sets have a special encoding in just one case: when a set is composed +# of just strings that happen to be integers in radix 10 in the range +# of 64 bit signed integers. +# The following configuration setting sets the limit in the size of the +# set in order to use this special memory saving encoding. +set-max-intset-entries 512 + +# Similarly to hashes and lists, sorted sets are also specially encoded in +# order to save a lot of space. This encoding is only used when the length and +# elements of a sorted set are below the following limits: +zset-max-ziplist-entries 128 +zset-max-ziplist-value 64 + +# HyperLogLog sparse representation bytes limit. The limit includes the +# 16 bytes header. When an HyperLogLog using the sparse representation crosses +# this limit, it is converted into the dense representation. +# +# A value greater than 16000 is totally useless, since at that point the +# dense representation is more memory efficient. +# +# The suggested value is ~ 3000 in order to have the benefits of +# the space efficient encoding without slowing down too much PFADD, +# which is O(N) with the sparse encoding. The value can be raised to +# ~ 10000 when CPU is not a concern, but space is, and the data set is +# composed of many HyperLogLogs with cardinality in the 0 - 15000 range. +hll-sparse-max-bytes 3000 + +# Streams macro node max size / items. The stream data structure is a radix +# tree of big nodes that encode multiple items inside. Using this configuration +# it is possible to configure how big a single node can be in bytes, and the +# maximum number of items it may contain before switching to a new node when +# appending new stream entries. If any of the following settings are set to +# zero, the limit is ignored, so for instance it is possible to set just a +# max entires limit by setting max-bytes to 0 and max-entries to the desired +# value. +stream-node-max-bytes 4096 +stream-node-max-entries 100 + +# Active rehashing uses 1 millisecond every 100 milliseconds of CPU time in +# order to help rehashing the main Redis hash table (the one mapping top-level +# keys to values). The hash table implementation Redis uses (see dict.c) +# performs a lazy rehashing: the more operation you run into a hash table +# that is rehashing, the more rehashing "steps" are performed, so if the +# server is idle the rehashing is never complete and some more memory is used +# by the hash table. +# +# The default is to use this millisecond 10 times every second in order to +# actively rehash the main dictionaries, freeing memory when possible. +# +# If unsure: +# use "activerehashing no" if you have hard latency requirements and it is +# not a good thing in your environment that Redis can reply from time to time +# to queries with 2 milliseconds delay. +# +# use "activerehashing yes" if you don't have such hard requirements but +# want to free memory asap when possible. +activerehashing yes + +# The client output buffer limits can be used to force disconnection of clients +# that are not reading data from the server fast enough for some reason (a +# common reason is that a Pub/Sub client can't consume messages as fast as the +# publisher can produce them). +# +# The limit can be set differently for the three different classes of clients: +# +# normal -> normal clients including MONITOR clients +# replica -> replica clients +# pubsub -> clients subscribed to at least one pubsub channel or pattern +# +# The syntax of every client-output-buffer-limit directive is the following: +# +# client-output-buffer-limit +# +# A client is immediately disconnected once the hard limit is reached, or if +# the soft limit is reached and remains reached for the specified number of +# seconds (continuously). +# So for instance if the hard limit is 32 megabytes and the soft limit is +# 16 megabytes / 10 seconds, the client will get disconnected immediately +# if the size of the output buffers reach 32 megabytes, but will also get +# disconnected if the client reaches 16 megabytes and continuously overcomes +# the limit for 10 seconds. +# +# By default normal clients are not limited because they don't receive data +# without asking (in a push way), but just after a request, so only +# asynchronous clients may create a scenario where data is requested faster +# than it can read. +# +# Instead there is a default limit for pubsub and replica clients, since +# subscribers and replicas receive data in a push fashion. +# +# Both the hard or the soft limit can be disabled by setting them to zero. +client-output-buffer-limit normal 0 0 0 +client-output-buffer-limit replica 256mb 64mb 60 +client-output-buffer-limit pubsub 32mb 8mb 60 + +# Client query buffers accumulate new commands. They are limited to a fixed +# amount by default in order to avoid that a protocol desynchronization (for +# instance due to a bug in the client) will lead to unbound memory usage in +# the query buffer. However you can configure it here if you have very special +# needs, such us huge multi/exec requests or alike. +# +# client-query-buffer-limit 1gb + +# In the Redis protocol, bulk requests, that are, elements representing single +# strings, are normally limited ot 512 mb. However you can change this limit +# here. +# +# proto-max-bulk-len 512mb + +# Redis calls an internal function to perform many background tasks, like +# closing connections of clients in timeout, purging expired keys that are +# never requested, and so forth. +# +# Not all tasks are performed with the same frequency, but Redis checks for +# tasks to perform according to the specified "hz" value. +# +# By default "hz" is set to 10. Raising the value will use more CPU when +# Redis is idle, but at the same time will make Redis more responsive when +# there are many keys expiring at the same time, and timeouts may be +# handled with more precision. +# +# The range is between 1 and 500, however a value over 100 is usually not +# a good idea. Most users should use the default of 10 and raise this up to +# 100 only in environments where very low latency is required. +hz 10 + +# Normally it is useful to have an HZ value which is proportional to the +# number of clients connected. This is useful in order, for instance, to +# avoid too many clients are processed for each background task invocation +# in order to avoid latency spikes. +# +# Since the default HZ value by default is conservatively set to 10, Redis +# offers, and enables by default, the ability to use an adaptive HZ value +# which will temporary raise when there are many connected clients. +# +# When dynamic HZ is enabled, the actual configured HZ will be used as +# as a baseline, but multiples of the configured HZ value will be actually +# used as needed once more clients are connected. In this way an idle +# instance will use very little CPU time while a busy instance will be +# more responsive. +dynamic-hz yes + +# When a child rewrites the AOF file, if the following option is enabled +# the file will be fsync-ed every 32 MB of data generated. This is useful +# in order to commit the file to the disk more incrementally and avoid +# big latency spikes. +aof-rewrite-incremental-fsync yes + +# When redis saves RDB file, if the following option is enabled +# the file will be fsync-ed every 32 MB of data generated. This is useful +# in order to commit the file to the disk more incrementally and avoid +# big latency spikes. +rdb-save-incremental-fsync yes + +# Redis LFU eviction (see maxmemory setting) can be tuned. However it is a good +# idea to start with the default settings and only change them after investigating +# how to improve the performances and how the keys LFU change over time, which +# is possible to inspect via the OBJECT FREQ command. +# +# There are two tunable parameters in the Redis LFU implementation: the +# counter logarithm factor and the counter decay time. It is important to +# understand what the two parameters mean before changing them. +# +# The LFU counter is just 8 bits per key, it's maximum value is 255, so Redis +# uses a probabilistic increment with logarithmic behavior. Given the value +# of the old counter, when a key is accessed, the counter is incremented in +# this way: +# +# 1. A random number R between 0 and 1 is extracted. +# 2. A probability P is calculated as 1/(old_value*lfu_log_factor+1). +# 3. The counter is incremented only if R < P. +# +# The default lfu-log-factor is 10. This is a table of how the frequency +# counter changes with a different number of accesses with different +# logarithmic factors: +# +# +--------+------------+------------+------------+------------+------------+ +# | factor | 100 hits | 1000 hits | 100K hits | 1M hits | 10M hits | +# +--------+------------+------------+------------+------------+------------+ +# | 0 | 104 | 255 | 255 | 255 | 255 | +# +--------+------------+------------+------------+------------+------------+ +# | 1 | 18 | 49 | 255 | 255 | 255 | +# +--------+------------+------------+------------+------------+------------+ +# | 10 | 10 | 18 | 142 | 255 | 255 | +# +--------+------------+------------+------------+------------+------------+ +# | 100 | 8 | 11 | 49 | 143 | 255 | +# +--------+------------+------------+------------+------------+------------+ +# +# NOTE: The above table was obtained by running the following commands: +# +# redis-benchmark -n 1000000 incr foo +# redis-cli object freq foo +# +# NOTE 2: The counter initial value is 5 in order to give new objects a chance +# to accumulate hits. +# +# The counter decay time is the time, in minutes, that must elapse in order +# for the key counter to be divided by two (or decremented if it has a value +# less <= 10). +# +# The default value for the lfu-decay-time is 1. A Special value of 0 means to +# decay the counter every time it happens to be scanned. +# +# lfu-log-factor 10 +# lfu-decay-time 1 + +################################## INCLUDES ################################### + +# Include one or more other config files here. This is useful if you +# have a standard template that goes to all Redis server but also need +# to customize a few per-server settings. Include files can include +# other files, so use this wisely. +# +# include /path/to/local.conf +# include /path/to/other.conf diff --git a/Redis-x64-5.0.14.1/redis.windows.conf b/Redis-x64-5.0.14.1/redis.windows.conf new file mode 100644 index 0000000..8233249 --- /dev/null +++ b/Redis-x64-5.0.14.1/redis.windows.conf @@ -0,0 +1,1336 @@ +# Redis configuration file example + +# Note on units: when memory size is needed, it is possible to specify +# it in the usual form of 1k 5GB 4M and so forth: +# +# 1k => 1000 bytes +# 1kb => 1024 bytes +# 1m => 1000000 bytes +# 1mb => 1024*1024 bytes +# 1g => 1000000000 bytes +# 1gb => 1024*1024*1024 bytes +# +# units are case insensitive so 1GB 1Gb 1gB are all the same. + +################################## INCLUDES ################################### + +# Include one or more other config files here. This is useful if you +# have a standard template that goes to all Redis servers but also need +# to customize a few per-server settings. Include files can include +# other files, so use this wisely. +# +# Notice option "include" won't be rewritten by command "CONFIG REWRITE" +# from admin or Redis Sentinel. Since Redis always uses the last processed +# line as value of a configuration directive, you'd better put includes +# at the beginning of this file to avoid overwriting config change at runtime. +# +# If instead you are interested in using includes to override configuration +# options, it is better to use include as the last line. +# +# include .\path\to\local.conf +# include c:\path\to\other.conf + +################################## MODULES ##################################### + +# Load modules at startup. If the server is not able to load modules +# it will abort. It is possible to use multiple loadmodule directives. +# +# loadmodule .\path\to\my_module.dll +# loadmodule c:\path\to\other_module.dll + +################################## NETWORK ##################################### + +# By default, if no "bind" configuration directive is specified, Redis listens +# for connections from all the network interfaces available on the server. +# It is possible to listen to just one or multiple selected interfaces using +# the "bind" configuration directive, followed by one or more IP addresses. +# +# Examples: +# +# bind 192.168.1.100 10.0.0.1 +# bind 127.0.0.1 ::1 +# +# ~~~ WARNING ~~~ If the computer running Redis is directly exposed to the +# internet, binding to all the interfaces is dangerous and will expose the +# instance to everybody on the internet. So by default we uncomment the +# following bind directive, that will force Redis to listen only into +# the IPv4 loopback interface address (this means Redis will be able to +# accept connections only from clients running into the same computer it +# is running). +# +# IF YOU ARE SURE YOU WANT YOUR INSTANCE TO LISTEN TO ALL THE INTERFACES +# JUST COMMENT THE FOLLOWING LINE. +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +bind 127.0.0.1 + +# Protected mode is a layer of security protection, in order to avoid that +# Redis instances left open on the internet are accessed and exploited. +# +# When protected mode is on and if: +# +# 1) The server is not binding explicitly to a set of addresses using the +# "bind" directive. +# 2) No password is configured. +# +# The server only accepts connections from clients connecting from the +# IPv4 and IPv6 loopback addresses 127.0.0.1 and ::1, and from Unix domain +# sockets. +# +# By default protected mode is enabled. You should disable it only if +# you are sure you want clients from other hosts to connect to Redis +# even if no authentication is configured, nor a specific set of interfaces +# are explicitly listed using the "bind" directive. +protected-mode yes + +# Accept connections on the specified port, default is 6379 (IANA #815344). +# If port 0 is specified Redis will not listen on a TCP socket. +port 6379 + +# TCP listen() backlog. +# +# In high requests-per-second environments you need an high backlog in order +# to avoid slow clients connections issues. Note that the Linux kernel +# will silently truncate it to the value of /proc/sys/net/core/somaxconn so +# make sure to raise both the value of somaxconn and tcp_max_syn_backlog +# in order to get the desired effect. +tcp-backlog 511 + +# Unix socket. +# +# Specify the path for the Unix socket that will be used to listen for +# incoming connections. There is no default, so Redis will not listen +# on a unix socket when not specified. +# +# unixsocket /tmp/redis.sock +# unixsocketperm 700 + +# Close the connection after a client is idle for N seconds (0 to disable) +timeout 0 + +# TCP keepalive. +# +# If non-zero, use SO_KEEPALIVE to send TCP ACKs to clients in absence +# of communication. This is useful for two reasons: +# +# 1) Detect dead peers. +# 2) Take the connection alive from the point of view of network +# equipment in the middle. +# +# On Linux, the specified value (in seconds) is the period used to send ACKs. +# Note that to close the connection the double of the time is needed. +# On other kernels the period depends on the kernel configuration. +# +# A reasonable value for this option is 300 seconds, which is the new +# Redis default starting with Redis 3.2.1. +tcp-keepalive 300 + +################################# GENERAL ##################################### + +# By default Redis does not run as a daemon. Use 'yes' if you need it. +# Note that Redis will write a pid file in /var/run/redis.pid when daemonized. +# NOT SUPPORTED ON WINDOWS daemonize no + +# If you run Redis from upstart or systemd, Redis can interact with your +# supervision tree. Options: +# supervised no - no supervision interaction +# supervised upstart - signal upstart by putting Redis into SIGSTOP mode +# supervised systemd - signal systemd by writing READY=1 to $NOTIFY_SOCKET +# supervised auto - detect upstart or systemd method based on +# UPSTART_JOB or NOTIFY_SOCKET environment variables +# Note: these supervision methods only signal "process is ready." +# They do not enable continuous liveness pings back to your supervisor. +# NOT SUPPORTED ON WINDOWS supervised no + +# If a pid file is specified, Redis writes it where specified at startup +# and removes it at exit. +# +# When the server runs non daemonized, no pid file is created if none is +# specified in the configuration. When the server is daemonized, the pid file +# is used even if not specified, defaulting to "/var/run/redis.pid". +# +# Creating a pid file is best effort: if Redis is not able to create it +# nothing bad happens, the server will start and run normally. +# NOT SUPPORTED ON WINDOWS pidfile /var/run/redis.pid + +# Specify the server verbosity level. +# This can be one of: +# debug (a lot of information, useful for development/testing) +# verbose (many rarely useful info, but not a mess like the debug level) +# notice (moderately verbose, what you want in production probably) +# warning (only very important / critical messages are logged) +loglevel notice + +# Specify the log file name. Also 'stdout' can be used to force +# Redis to log on the standard output. +logfile "" + +# To enable logging to the Windows EventLog, just set 'syslog-enabled' to +# yes, and optionally update the other syslog parameters to suit your needs. +# If Redis is installed and launched as a Windows Service, this will +# automatically be enabled. +# syslog-enabled no + +# Specify the source name of the events in the Windows Application log. +# syslog-ident redis + +# Specify the syslog facility. Must be USER or between LOCAL0-LOCAL7. +# NOT SUPPORTED ON WINDOWS syslog-facility local0 + +# Set the number of databases. The default database is DB 0, you can select +# a different one on a per-connection basis using SELECT where +# dbid is a number between 0 and 'databases'-1 +databases 16 + +# By default Redis shows an ASCII art logo only when started to log to the +# standard output and if the standard output is a TTY. Basically this means +# that normally a logo is displayed only in interactive sessions. +# +# However it is possible to force the pre-4.0 behavior and always show a +# ASCII art logo in startup logs by setting the following option to yes. +always-show-logo yes + +################################ SNAPSHOTTING ################################ +# +# Save the DB on disk: +# +# save +# +# Will save the DB if both the given number of seconds and the given +# number of write operations against the DB occurred. +# +# In the example below the behaviour will be to save: +# after 900 sec (15 min) if at least 1 key changed +# after 300 sec (5 min) if at least 10 keys changed +# after 60 sec if at least 10000 keys changed +# +# Note: you can disable saving completely by commenting out all "save" lines. +# +# It is also possible to remove all the previously configured save +# points by adding a save directive with a single empty string argument +# like in the following example: +# +# save "" + +save 900 1 +save 300 10 +save 60 10000 + +# By default Redis will stop accepting writes if RDB snapshots are enabled +# (at least one save point) and the latest background save failed. +# This will make the user aware (in a hard way) that data is not persisting +# on disk properly, otherwise chances are that no one will notice and some +# disaster will happen. +# +# If the background saving process will start working again Redis will +# automatically allow writes again. +# +# However if you have setup your proper monitoring of the Redis server +# and persistence, you may want to disable this feature so that Redis will +# continue to work as usual even if there are problems with disk, +# permissions, and so forth. +stop-writes-on-bgsave-error yes + +# Compress string objects using LZF when dump .rdb databases? +# For default that's set to 'yes' as it's almost always a win. +# If you want to save some CPU in the saving child set it to 'no' but +# the dataset will likely be bigger if you have compressible values or keys. +rdbcompression yes + +# Since version 5 of RDB a CRC64 checksum is placed at the end of the file. +# This makes the format more resistant to corruption but there is a performance +# hit to pay (around 10%) when saving and loading RDB files, so you can disable it +# for maximum performances. +# +# RDB files created with checksum disabled have a checksum of zero that will +# tell the loading code to skip the check. +rdbchecksum yes + +# The filename where to dump the DB +dbfilename dump.rdb + +# The working directory. +# +# The DB will be written inside this directory, with the filename specified +# above using the 'dbfilename' configuration directive. +# +# The Append Only File will also be created inside this directory. +# +# Note that you must specify a directory here, not a file name. +dir ./ + +################################# REPLICATION ################################# + +# Master-Replica replication. Use replicaof to make a Redis instance a copy of +# another Redis server. A few things to understand ASAP about Redis replication. +# +# +------------------+ +---------------+ +# | Master | ---> | Replica | +# | (receive writes) | | (exact copy) | +# +------------------+ +---------------+ +# +# 1) Redis replication is asynchronous, but you can configure a master to +# stop accepting writes if it appears to be not connected with at least +# a given number of replicas. +# 2) Redis replicas are able to perform a partial resynchronization with the +# master if the replication link is lost for a relatively small amount of +# time. You may want to configure the replication backlog size (see the next +# sections of this file) with a sensible value depending on your needs. +# 3) Replication is automatic and does not need user intervention. After a +# network partition replicas automatically try to reconnect to masters +# and resynchronize with them. +# +# replicaof + +# If the master is password protected (using the "requirepass" configuration +# directive below) it is possible to tell the replica to authenticate before +# starting the replication synchronization process, otherwise the master will +# refuse the replica request. +# +# masterauth + +# When a replica loses its connection with the master, or when the replication +# is still in progress, the replica can act in two different ways: +# +# 1) if replica-serve-stale-data is set to 'yes' (the default) the replica will +# still reply to client requests, possibly with out of date data, or the +# data set may just be empty if this is the first synchronization. +# +# 2) if replica-serve-stale-data is set to 'no' the replica will reply with +# an error "SYNC with master in progress" to all the kind of commands +# but to INFO, replicaOF, AUTH, PING, SHUTDOWN, REPLCONF, ROLE, CONFIG, +# SUBSCRIBE, UNSUBSCRIBE, PSUBSCRIBE, PUNSUBSCRIBE, PUBLISH, PUBSUB, +# COMMAND, POST, HOST: and LATENCY. +# +replica-serve-stale-data yes + +# You can configure a replica instance to accept writes or not. Writing against +# a replica instance may be useful to store some ephemeral data (because data +# written on a replica will be easily deleted after resync with the master) but +# may also cause problems if clients are writing to it because of a +# misconfiguration. +# +# Since Redis 2.6 by default replicas are read-only. +# +# Note: read only replicas are not designed to be exposed to untrusted clients +# on the internet. It's just a protection layer against misuse of the instance. +# Still a read only replica exports by default all the administrative commands +# such as CONFIG, DEBUG, and so forth. To a limited extent you can improve +# security of read only replicas using 'rename-command' to shadow all the +# administrative / dangerous commands. +replica-read-only yes + +# Replication SYNC strategy: disk or socket. +# +# ------------------------------------------------------- +# WARNING: DISKLESS REPLICATION IS EXPERIMENTAL CURRENTLY +# ------------------------------------------------------- +# +# New replicas and reconnecting replicas that are not able to continue the replication +# process just receiving differences, need to do what is called a "full +# synchronization". An RDB file is transmitted from the master to the replicas. +# The transmission can happen in two different ways: +# +# 1) Disk-backed: The Redis master creates a new process that writes the RDB +# file on disk. Later the file is transferred by the parent +# process to the replicas incrementally. +# 2) Diskless: The Redis master creates a new process that directly writes the +# RDB file to replica sockets, without touching the disk at all. +# +# With disk-backed replication, while the RDB file is generated, more replicas +# can be queued and served with the RDB file as soon as the current child producing +# the RDB file finishes its work. With diskless replication instead once +# the transfer starts, new replicas arriving will be queued and a new transfer +# will start when the current one terminates. +# +# When diskless replication is used, the master waits a configurable amount of +# time (in seconds) before starting the transfer in the hope that multiple replicas +# will arrive and the transfer can be parallelized. +# +# With slow disks and fast (large bandwidth) networks, diskless replication +# works better. +repl-diskless-sync no + +# When diskless replication is enabled, it is possible to configure the delay +# the server waits in order to spawn the child that transfers the RDB via socket +# to the replicas. +# +# This is important since once the transfer starts, it is not possible to serve +# new replicas arriving, that will be queued for the next RDB transfer, so the server +# waits a delay in order to let more replicas arrive. +# +# The delay is specified in seconds, and by default is 5 seconds. To disable +# it entirely just set it to 0 seconds and the transfer will start ASAP. +repl-diskless-sync-delay 5 + +# Replicas send PINGs to server in a predefined interval. It's possible to change +# this interval with the repl_ping_replica_period option. The default value is 10 +# seconds. +# +# repl-ping-replica-period 10 + +# The following option sets the replication timeout for: +# +# 1) Bulk transfer I/O during SYNC, from the point of view of replica. +# 2) Master timeout from the point of view of replicas (data, pings). +# 3) Replica timeout from the point of view of masters (REPLCONF ACK pings). +# +# It is important to make sure that this value is greater than the value +# specified for repl-ping-replica-period otherwise a timeout will be detected +# every time there is low traffic between the master and the replica. +# +# repl-timeout 60 + +# Disable TCP_NODELAY on the replica socket after SYNC? +# +# If you select "yes" Redis will use a smaller number of TCP packets and +# less bandwidth to send data to replicas. But this can add a delay for +# the data to appear on the replica side, up to 40 milliseconds with +# Linux kernels using a default configuration. +# +# If you select "no" the delay for data to appear on the replica side will +# be reduced but more bandwidth will be used for replication. +# +# By default we optimize for low latency, but in very high traffic conditions +# or when the master and replicas are many hops away, turning this to "yes" may +# be a good idea. +repl-disable-tcp-nodelay no + +# Set the replication backlog size. The backlog is a buffer that accumulates +# replica data when replicas are disconnected for some time, so that when a replica +# wants to reconnect again, often a full resync is not needed, but a partial +# resync is enough, just passing the portion of data the replica missed while +# disconnected. +# +# The bigger the replication backlog, the longer the time the replica can be +# disconnected and later be able to perform a partial resynchronization. +# +# The backlog is only allocated once there is at least a replica connected. +# +# repl-backlog-size 1mb + +# After a master has no longer connected replicas for some time, the backlog +# will be freed. The following option configures the amount of seconds that +# need to elapse, starting from the time the last replica disconnected, for +# the backlog buffer to be freed. +# +# Note that replicas never free the backlog for timeout, since they may be +# promoted to masters later, and should be able to correctly "partially +# resynchronize" with the replicas: hence they should always accumulate backlog. +# +# A value of 0 means to never release the backlog. +# +# repl-backlog-ttl 3600 + +# The replica priority is an integer number published by Redis in the INFO output. +# It is used by Redis Sentinel in order to select a replica to promote into a +# master if the master is no longer working correctly. +# +# A replica with a low priority number is considered better for promotion, so +# for instance if there are three replicas with priority 10, 100, 25 Sentinel will +# pick the one with priority 10, that is the lowest. +# +# However a special priority of 0 marks the replica as not able to perform the +# role of master, so a replica with priority of 0 will never be selected by +# Redis Sentinel for promotion. +# +# By default the priority is 100. +replica-priority 100 + +# It is possible for a master to stop accepting writes if there are less than +# N replicas connected, having a lag less or equal than M seconds. +# +# The N replicas need to be in "online" state. +# +# The lag in seconds, that must be <= the specified value, is calculated from +# the last ping received from the replica, that is usually sent every second. +# +# This option does not GUARANTEE that N replicas will accept the write, but +# will limit the window of exposure for lost writes in case not enough replicas +# are available, to the specified number of seconds. +# +# For example to require at least 3 replicas with a lag <= 10 seconds use: +# +# min-replicas-to-write 3 +# min-replicas-max-lag 10 +# +# Setting one or the other to 0 disables the feature. +# +# By default min-replicas-to-write is set to 0 (feature disabled) and +# min-replicas-max-lag is set to 10. + +# A Redis master is able to list the address and port of the attached +# replicas in different ways. For example the "INFO replication" section +# offers this information, which is used, among other tools, by +# Redis Sentinel in order to discover replica instances. +# Another place where this info is available is in the output of the +# "ROLE" command of a master. +# +# The listed IP and address normally reported by a replica is obtained +# in the following way: +# +# IP: The address is auto detected by checking the peer address +# of the socket used by the replica to connect with the master. +# +# Port: The port is communicated by the replica during the replication +# handshake, and is normally the port that the replica is using to +# listen for connections. +# +# However when port forwarding or Network Address Translation (NAT) is +# used, the replica may be actually reachable via different IP and port +# pairs. The following two options can be used by a replica in order to +# report to its master a specific set of IP and port, so that both INFO +# and ROLE will report those values. +# +# There is no need to use both the options if you need to override just +# the port or the IP address. +# +# replica-announce-ip 5.5.5.5 +# replica-announce-port 1234 + +################################## SECURITY ################################### + +# Require clients to issue AUTH before processing any other +# commands. This might be useful in environments in which you do not trust +# others with access to the host running redis-server. +# +# This should stay commented out for backward compatibility and because most +# people do not need auth (e.g. they run their own servers). +# +# Warning: since Redis is pretty fast an outside user can try up to +# 150k passwords per second against a good box. This means that you should +# use a very strong password otherwise it will be very easy to break. +# +# requirepass foobared + +# Command renaming. +# +# It is possible to change the name of dangerous commands in a shared +# environment. For instance the CONFIG command may be renamed into something +# hard to guess so that it will still be available for internal-use tools +# but not available for general clients. +# +# Example: +# +# rename-command CONFIG b840fc02d524045429941cc15f59e41cb7be6c52 +# +# It is also possible to completely kill a command by renaming it into +# an empty string: +# +# rename-command CONFIG "" +# +# Please note that changing the name of commands that are logged into the +# AOF file or transmitted to replicas may cause problems. + +################################### CLIENTS #################################### + +# Set the max number of connected clients at the same time. By default +# this limit is set to 10000 clients, however if the Redis server is not +# able to configure the process file limit to allow for the specified limit +# the max number of allowed clients is set to the current file limit +# minus 32 (as Redis reserves a few file descriptors for internal uses). +# +# Once the limit is reached Redis will close all the new connections sending +# an error 'max number of clients reached'. +# +# maxclients 10000 + +############################## MEMORY MANAGEMENT ################################ + +# If Redis is to be used as an in-memory-only cache without any kind of +# persistence, then the fork() mechanism used by the background AOF/RDB +# persistence is unnecessary. As an optimization, all persistence can be +# turned off in the Windows version of Redis. This will redirect heap +# allocations to the system heap allocator, and disable commands that would +# otherwise cause fork() operations: BGSAVE and BGREWRITEAOF. +# This flag may not be combined with any of the other flags that configure +# AOF and RDB operations. +# persistence-available [(yes)|no] + +# Set a memory usage limit to the specified amount of bytes. +# When the memory limit is reached Redis will try to remove keys +# according to the eviction policy selected (see maxmemory-policy). +# +# If Redis can't remove keys according to the policy, or if the policy is +# set to 'noeviction', Redis will start to reply with errors to commands +# that would use more memory, like SET, LPUSH, and so on, and will continue +# to reply to read-only commands like GET. +# +# This option is usually useful when using Redis as an LRU or LFU cache, or to +# set a hard memory limit for an instance (using the 'noeviction' policy). +# +# WARNING: If you have replicas attached to an instance with maxmemory on, +# the size of the output buffers needed to feed the replicas are subtracted +# from the used memory count, so that network problems / resyncs will +# not trigger a loop where keys are evicted, and in turn the output +# buffer of replicas is full with DELs of keys evicted triggering the deletion +# of more keys, and so forth until the database is completely emptied. +# +# In short... if you have replicas attached it is suggested that you set a lower +# limit for maxmemory so that there is some free RAM on the system for replica +# output buffers (but this is not needed if the policy is 'noeviction'). +# +# WARNING: not setting maxmemory will cause Redis to terminate with an +# out-of-memory exception if the heap limit is reached. +# +# NOTE: since Redis uses the system paging file to allocate the heap memory, +# the Working Set memory usage showed by the Windows Task Manager or by other +# tools such as ProcessExplorer will not always be accurate. For example, right +# after a background save of the RDB or the AOF files, the working set value +# may drop significantly. In order to check the correct amount of memory used +# by the redis-server to store the data, use the INFO client command. The INFO +# command shows only the memory used to store the redis data, not the extra +# memory used by the Windows process for its own requirements. Th3 extra amount +# of memory not reported by the INFO command can be calculated subtracting the +# Peak Working Set reported by the Windows Task Manager and the used_memory_peak +# reported by the INFO command. +# +# maxmemory + +# MAXMEMORY POLICY: how Redis will select what to remove when maxmemory +# is reached. You can select among five behaviors: +# +# volatile-lru -> Evict using approximated LRU among the keys with an expire set. +# allkeys-lru -> Evict any key using approximated LRU. +# volatile-lfu -> Evict using approximated LFU among the keys with an expire set. +# allkeys-lfu -> Evict any key using approximated LFU. +# volatile-random -> Remove a random key among the ones with an expire set. +# allkeys-random -> Remove a random key, any key. +# volatile-ttl -> Remove the key with the nearest expire time (minor TTL) +# noeviction -> Don't evict anything, just return an error on write operations. +# +# LRU means Least Recently Used +# LFU means Least Frequently Used +# +# Both LRU, LFU and volatile-ttl are implemented using approximated +# randomized algorithms. +# +# Note: with any of the above policies, Redis will return an error on write +# operations, when there are no suitable keys for eviction. +# +# At the date of writing these commands are: set setnx setex append +# incr decr rpush lpush rpushx lpushx linsert lset rpoplpush sadd +# sinter sinterstore sunion sunionstore sdiff sdiffstore zadd zincrby +# zunionstore zinterstore hset hsetnx hmset hincrby incrby decrby +# getset mset msetnx exec sort +# +# The default is: +# +# maxmemory-policy noeviction + +# LRU, LFU and minimal TTL algorithms are not precise algorithms but approximated +# algorithms (in order to save memory), so you can tune it for speed or +# accuracy. For default Redis will check five keys and pick the one that was +# used less recently, you can change the sample size using the following +# configuration directive. +# +# The default of 5 produces good enough results. 10 Approximates very closely +# true LRU but costs more CPU. 3 is faster but not very accurate. +# +# maxmemory-samples 5 + +# Starting from Redis 5, by default a replica will ignore its maxmemory setting +# (unless it is promoted to master after a failover or manually). It means +# that the eviction of keys will be just handled by the master, sending the +# DEL commands to the replica as keys evict in the master side. +# +# This behavior ensures that masters and replicas stay consistent, and is usually +# what you want, however if your replica is writable, or you want the replica to have +# a different memory setting, and you are sure all the writes performed to the +# replica are idempotent, then you may change this default (but be sure to understand +# what you are doing). +# +# Note that since the replica by default does not evict, it may end using more +# memory than the one set via maxmemory (there are certain buffers that may +# be larger on the replica, or data structures may sometimes take more memory and so +# forth). So make sure you monitor your replicas and make sure they have enough +# memory to never hit a real out-of-memory condition before the master hits +# the configured maxmemory setting. +# +# replica-ignore-maxmemory yes + +############################# LAZY FREEING #################################### + +# Redis has two primitives to delete keys. One is called DEL and is a blocking +# deletion of the object. It means that the server stops processing new commands +# in order to reclaim all the memory associated with an object in a synchronous +# way. If the key deleted is associated with a small object, the time needed +# in order to execute the DEL command is very small and comparable to most other +# O(1) or O(log_N) commands in Redis. However if the key is associated with an +# aggregated value containing millions of elements, the server can block for +# a long time (even seconds) in order to complete the operation. +# +# For the above reasons Redis also offers non blocking deletion primitives +# such as UNLINK (non blocking DEL) and the ASYNC option of FLUSHALL and +# FLUSHDB commands, in order to reclaim memory in background. Those commands +# are executed in constant time. Another thread will incrementally free the +# object in the background as fast as possible. +# +# DEL, UNLINK and ASYNC option of FLUSHALL and FLUSHDB are user-controlled. +# It's up to the design of the application to understand when it is a good +# idea to use one or the other. However the Redis server sometimes has to +# delete keys or flush the whole database as a side effect of other operations. +# Specifically Redis deletes objects independently of a user call in the +# following scenarios: +# +# 1) On eviction, because of the maxmemory and maxmemory policy configurations, +# in order to make room for new data, without going over the specified +# memory limit. +# 2) Because of expire: when a key with an associated time to live (see the +# EXPIRE command) must be deleted from memory. +# 3) Because of a side effect of a command that stores data on a key that may +# already exist. For example the RENAME command may delete the old key +# content when it is replaced with another one. Similarly SUNIONSTORE +# or SORT with STORE option may delete existing keys. The SET command +# itself removes any old content of the specified key in order to replace +# it with the specified string. +# 4) During replication, when a replica performs a full resynchronization with +# its master, the content of the whole database is removed in order to +# load the RDB file just transferred. +# +# In all the above cases the default is to delete objects in a blocking way, +# like if DEL was called. However you can configure each case specifically +# in order to instead release memory in a non-blocking way like if UNLINK +# was called, using the following configuration directives: + +lazyfree-lazy-eviction no +lazyfree-lazy-expire no +lazyfree-lazy-server-del no +replica-lazy-flush no + +############################## APPEND ONLY MODE ############################### + +# By default Redis asynchronously dumps the dataset on disk. This mode is +# good enough in many applications, but an issue with the Redis process or +# a power outage may result into a few minutes of writes lost (depending on +# the configured save points). +# +# The Append Only File is an alternative persistence mode that provides +# much better durability. For instance using the default data fsync policy +# (see later in the config file) Redis can lose just one second of writes in a +# dramatic event like a server power outage, or a single write if something +# wrong with the Redis process itself happens, but the operating system is +# still running correctly. +# +# AOF and RDB persistence can be enabled at the same time without problems. +# If the AOF is enabled on startup Redis will load the AOF, that is the file +# with the better durability guarantees. +# +# Please check http://redis.io/topics/persistence for more information. + +appendonly no + +# The name of the append only file (default: "appendonly.aof") + +appendfilename "appendonly.aof" + +# The fsync() call tells the Operating System to actually write data on disk +# instead of waiting for more data in the output buffer. Some OS will really flush +# data on disk, some other OS will just try to do it ASAP. +# +# Redis supports three different modes: +# +# no: don't fsync, just let the OS flush the data when it wants. Faster. +# always: fsync after every write to the append only log. Slow, Safest. +# everysec: fsync only one time every second. Compromise. +# +# The default is "everysec", as that's usually the right compromise between +# speed and data safety. It's up to you to understand if you can relax this to +# "no" that will let the operating system flush the output buffer when +# it wants, for better performances (but if you can live with the idea of +# some data loss consider the default persistence mode that's snapshotting), +# or on the contrary, use "always" that's very slow but a bit safer than +# everysec. +# +# More details please check the following article: +# http://antirez.com/post/redis-persistence-demystified.html +# +# If unsure, use "everysec". + +# appendfsync always +appendfsync everysec +# appendfsync no + +# When the AOF fsync policy is set to always or everysec, and a background +# saving process (a background save or AOF log background rewriting) is +# performing a lot of I/O against the disk, in some Linux configurations +# Redis may block too long on the fsync() call. Note that there is no fix for +# this currently, as even performing fsync in a different thread will block +# our synchronous write(2) call. +# +# In order to mitigate this problem it's possible to use the following option +# that will prevent fsync() from being called in the main process while a +# BGSAVE or BGREWRITEAOF is in progress. +# +# This means that while another child is saving, the durability of Redis is +# the same as "appendfsync none". In practical terms, this means that it is +# possible to lose up to 30 seconds of log in the worst scenario (with the +# default Linux settings). +# +# If you have latency problems turn this to "yes". Otherwise leave it as +# "no" that is the safest pick from the point of view of durability. + +no-appendfsync-on-rewrite no + +# Automatic rewrite of the append only file. +# Redis is able to automatically rewrite the log file implicitly calling +# BGREWRITEAOF when the AOF log size grows by the specified percentage. +# +# This is how it works: Redis remembers the size of the AOF file after the +# latest rewrite (if no rewrite has happened since the restart, the size of +# the AOF at startup is used). +# +# This base size is compared to the current size. If the current size is +# bigger than the specified percentage, the rewrite is triggered. Also +# you need to specify a minimal size for the AOF file to be rewritten, this +# is useful to avoid rewriting the AOF file even if the percentage increase +# is reached but it is still pretty small. +# +# Specify a percentage of zero in order to disable the automatic AOF +# rewrite feature. + +auto-aof-rewrite-percentage 100 +auto-aof-rewrite-min-size 64mb + +# An AOF file may be found to be truncated at the end during the Redis +# startup process, when the AOF data gets loaded back into memory. +# This may happen when the system where Redis is running +# crashes, especially when an ext4 filesystem is mounted without the +# data=ordered option (however this can't happen when Redis itself +# crashes or aborts but the operating system still works correctly). +# +# Redis can either exit with an error when this happens, or load as much +# data as possible (the default now) and start if the AOF file is found +# to be truncated at the end. The following option controls this behavior. +# +# If aof-load-truncated is set to yes, a truncated AOF file is loaded and +# the Redis server starts emitting a log to inform the user of the event. +# Otherwise if the option is set to no, the server aborts with an error +# and refuses to start. When the option is set to no, the user requires +# to fix the AOF file using the "redis-check-aof" utility before to restart +# the server. +# +# Note that if the AOF file will be found to be corrupted in the middle +# the server will still exit with an error. This option only applies when +# Redis will try to read more data from the AOF file but not enough bytes +# will be found. +aof-load-truncated yes + +# When rewriting the AOF file, Redis is able to use an RDB preamble in the +# AOF file for faster rewrites and recoveries. When this option is turned +# on the rewritten AOF file is composed of two different stanzas: +# +# [RDB file][AOF tail] +# +# When loading Redis recognizes that the AOF file starts with the "REDIS" +# string and loads the prefixed RDB file, and continues loading the AOF +# tail. +aof-use-rdb-preamble yes + +################################ LUA SCRIPTING ############################### + +# Max execution time of a Lua script in milliseconds. +# +# If the maximum execution time is reached Redis will log that a script is +# still in execution after the maximum allowed time and will start to +# reply to queries with an error. +# +# When a long running script exceeds the maximum execution time only the +# SCRIPT KILL and SHUTDOWN NOSAVE commands are available. The first can be +# used to stop a script that did not yet called write commands. The second +# is the only way to shut down the server in the case a write command was +# already issued by the script but the user doesn't want to wait for the natural +# termination of the script. +# +# Set it to 0 or a negative value for unlimited execution without warnings. +lua-time-limit 5000 + +################################ REDIS CLUSTER ############################### + +# Normal Redis instances can't be part of a Redis Cluster; only nodes that are +# started as cluster nodes can. In order to start a Redis instance as a +# cluster node enable the cluster support uncommenting the following: +# +# cluster-enabled yes + +# Every cluster node has a cluster configuration file. This file is not +# intended to be edited by hand. It is created and updated by Redis nodes. +# Every Redis Cluster node requires a different cluster configuration file. +# Make sure that instances running in the same system do not have +# overlapping cluster configuration file names. +# +# cluster-config-file nodes-6379.conf + +# Cluster node timeout is the amount of milliseconds a node must be unreachable +# for it to be considered in failure state. +# Most other internal time limits are multiple of the node timeout. +# +# cluster-node-timeout 15000 + +# A replica of a failing master will avoid to start a failover if its data +# looks too old. +# +# There is no simple way for a replica to actually have an exact measure of +# its "data age", so the following two checks are performed: +# +# 1) If there are multiple replicas able to failover, they exchange messages +# in order to try to give an advantage to the replica with the best +# replication offset (more data from the master processed). +# Replicas will try to get their rank by offset, and apply to the start +# of the failover a delay proportional to their rank. +# +# 2) Every single replica computes the time of the last interaction with +# its master. This can be the last ping or command received (if the master +# is still in the "connected" state), or the time that elapsed since the +# disconnection with the master (if the replication link is currently down). +# If the last interaction is too old, the replica will not try to failover +# at all. +# +# The point "2" can be tuned by user. Specifically a replica will not perform +# the failover if, since the last interaction with the master, the time +# elapsed is greater than: +# +# (node-timeout * replica-validity-factor) + repl-ping-replica-period +# +# So for example if node-timeout is 30 seconds, and the replica-validity-factor +# is 10, and assuming a default repl-ping-replica-period of 10 seconds, the +# replica will not try to failover if it was not able to talk with the master +# for longer than 310 seconds. +# +# A large replica-validity-factor may allow replicas with too old data to failover +# a master, while a too small value may prevent the cluster from being able to +# elect a replica at all. +# +# For maximum availability, it is possible to set the replica-validity-factor +# to a value of 0, which means, that replicas will always try to failover the +# master regardless of the last time they interacted with the master. +# (However they'll always try to apply a delay proportional to their +# offset rank). +# +# Zero is the only value able to guarantee that when all the partitions heal +# the cluster will always be able to continue. +# +# cluster-replica-validity-factor 10 + +# Cluster replicas are able to migrate to orphaned masters, that are masters +# that are left without working replicas. This improves the cluster ability +# to resist to failures as otherwise an orphaned master can't be failed over +# in case of failure if it has no working replicas. +# +# Replicas migrate to orphaned masters only if there are still at least a +# given number of other working replicas for their old master. This number +# is the "migration barrier". A migration barrier of 1 means that a replica +# will migrate only if there is at least 1 other working replica for its master +# and so forth. It usually reflects the number of replicas you want for every +# master in your cluster. +# +# Default is 1 (replicas migrate only if their masters remain with at least +# one replica). To disable migration just set it to a very large value. +# A value of 0 can be set but is useful only for debugging and dangerous +# in production. +# +# cluster-migration-barrier 1 + +# By default Redis Cluster nodes stop accepting queries if they detect there +# is at least an hash slot uncovered (no available node is serving it). +# This way if the cluster is partially down (for example a range of hash slots +# are no longer covered) all the cluster becomes, eventually, unavailable. +# It automatically returns available as soon as all the slots are covered again. +# +# However sometimes you want the subset of the cluster which is working, +# to continue to accept queries for the part of the key space that is still +# covered. In order to do so, just set the cluster-require-full-coverage +# option to no. +# +# cluster-require-full-coverage yes + +# This option, when set to yes, prevents replicas from trying to failover its +# master during master failures. However the master can still perform a +# manual failover, if forced to do so. +# +# This is useful in different scenarios, especially in the case of multiple +# data center operations, where we want one side to never be promoted if not +# in the case of a total DC failure. +# +# cluster-replica-no-failover no + +# In order to setup your cluster make sure to read the documentation +# available at http://redis.io web site. + +########################## CLUSTER DOCKER/NAT support ######################## + +# In certain deployments, Redis Cluster nodes address discovery fails, because +# addresses are NAT-ted or because ports are forwarded (the typical case is +# Docker and other containers). +# +# In order to make Redis Cluster working in such environments, a static +# configuration where each node knows its public address is needed. The +# following two options are used for this scope, and are: +# +# * cluster-announce-ip +# * cluster-announce-port +# * cluster-announce-bus-port +# +# Each instruct the node about its address, client port, and cluster message +# bus port. The information is then published in the header of the bus packets +# so that other nodes will be able to correctly map the address of the node +# publishing the information. +# +# If the above options are not used, the normal Redis Cluster auto-detection +# will be used instead. +# +# Note that when remapped, the bus port may not be at the fixed offset of +# clients port + 10000, so you can specify any port and bus-port depending +# on how they get remapped. If the bus-port is not set, a fixed offset of +# 10000 will be used as usually. +# +# Example: +# +# cluster-announce-ip 10.1.1.5 +# cluster-announce-port 6379 +# cluster-announce-bus-port 6380 + +################################## SLOW LOG ################################### + +# The Redis Slow Log is a system to log queries that exceeded a specified +# execution time. The execution time does not include the I/O operations +# like talking with the client, sending the reply and so forth, +# but just the time needed to actually execute the command (this is the only +# stage of command execution where the thread is blocked and can not serve +# other requests in the meantime). +# +# You can configure the slow log with two parameters: one tells Redis +# what is the execution time, in microseconds, to exceed in order for the +# command to get logged, and the other parameter is the length of the +# slow log. When a new command is logged the oldest one is removed from the +# queue of logged commands. + +# The following time is expressed in microseconds, so 1000000 is equivalent +# to one second. Note that a negative number disables the slow log, while +# a value of zero forces the logging of every command. +slowlog-log-slower-than 10000 + +# There is no limit to this length. Just be aware that it will consume memory. +# You can reclaim memory used by the slow log with SLOWLOG RESET. +slowlog-max-len 128 + +################################ LATENCY MONITOR ############################## + +# The Redis latency monitoring subsystem samples different operations +# at runtime in order to collect data related to possible sources of +# latency of a Redis instance. +# +# Via the LATENCY command this information is available to the user that can +# print graphs and obtain reports. +# +# The system only logs operations that were performed in a time equal or +# greater than the amount of milliseconds specified via the +# latency-monitor-threshold configuration directive. When its value is set +# to zero, the latency monitor is turned off. +# +# By default latency monitoring is disabled since it is mostly not needed +# if you don't have latency issues, and collecting data has a performance +# impact, that while very small, can be measured under big load. Latency +# monitoring can easily be enabled at runtime using the command +# "CONFIG SET latency-monitor-threshold " if needed. +latency-monitor-threshold 0 + +############################# EVENT NOTIFICATION ############################## + +# Redis can notify Pub/Sub clients about events happening in the key space. +# This feature is documented at http://redis.io/topics/notifications +# +# For instance if keyspace events notification is enabled, and a client +# performs a DEL operation on key "foo" stored in the Database 0, two +# messages will be published via Pub/Sub: +# +# PUBLISH __keyspace@0__:foo del +# PUBLISH __keyevent@0__:del foo +# +# It is possible to select the events that Redis will notify among a set +# of classes. Every class is identified by a single character: +# +# K Keyspace events, published with __keyspace@__ prefix. +# E Keyevent events, published with __keyevent@__ prefix. +# g Generic commands (non-type specific) like DEL, EXPIRE, RENAME, ... +# $ String commands +# l List commands +# s Set commands +# h Hash commands +# z Sorted set commands +# x Expired events (events generated every time a key expires) +# e Evicted events (events generated when a key is evicted for maxmemory) +# A Alias for g$lshzxe, so that the "AKE" string means all the events. +# +# The "notify-keyspace-events" takes as argument a string that is composed +# of zero or multiple characters. The empty string means that notifications +# are disabled. +# +# Example: to enable list and generic events, from the point of view of the +# event name, use: +# +# notify-keyspace-events Elg +# +# Example 2: to get the stream of the expired keys subscribing to channel +# name __keyevent@0__:expired use: +# +# notify-keyspace-events Ex +# +# By default all notifications are disabled because most users don't need +# this feature and the feature has some overhead. Note that if you don't +# specify at least one of K or E, no events will be delivered. +notify-keyspace-events "" + +############################### ADVANCED CONFIG ############################### + +# Hashes are encoded using a memory efficient data structure when they have a +# small number of entries, and the biggest entry does not exceed a given +# threshold. These thresholds can be configured using the following directives. +hash-max-ziplist-entries 512 +hash-max-ziplist-value 64 + +# Lists are also encoded in a special way to save a lot of space. +# The number of entries allowed per internal list node can be specified +# as a fixed maximum size or a maximum number of elements. +# For a fixed maximum size, use -5 through -1, meaning: +# -5: max size: 64 Kb <-- not recommended for normal workloads +# -4: max size: 32 Kb <-- not recommended +# -3: max size: 16 Kb <-- probably not recommended +# -2: max size: 8 Kb <-- good +# -1: max size: 4 Kb <-- good +# Positive numbers mean store up to _exactly_ that number of elements +# per list node. +# The highest performing option is usually -2 (8 Kb size) or -1 (4 Kb size), +# but if your use case is unique, adjust the settings as necessary. +list-max-ziplist-size -2 + +# Lists may also be compressed. +# Compress depth is the number of quicklist ziplist nodes from *each* side of +# the list to *exclude* from compression. The head and tail of the list +# are always uncompressed for fast push/pop operations. Settings are: +# 0: disable all list compression +# 1: depth 1 means "don't start compressing until after 1 node into the list, +# going from either the head or tail" +# So: [head]->node->node->...->node->[tail] +# [head], [tail] will always be uncompressed; inner nodes will compress. +# 2: [head]->[next]->node->node->...->node->[prev]->[tail] +# 2 here means: don't compress head or head->next or tail->prev or tail, +# but compress all nodes between them. +# 3: [head]->[next]->[next]->node->node->...->node->[prev]->[prev]->[tail] +# etc. +list-compress-depth 0 + +# Sets have a special encoding in just one case: when a set is composed +# of just strings that happen to be integers in radix 10 in the range +# of 64 bit signed integers. +# The following configuration setting sets the limit in the size of the +# set in order to use this special memory saving encoding. +set-max-intset-entries 512 + +# Similarly to hashes and lists, sorted sets are also specially encoded in +# order to save a lot of space. This encoding is only used when the length and +# elements of a sorted set are below the following limits: +zset-max-ziplist-entries 128 +zset-max-ziplist-value 64 + +# HyperLogLog sparse representation bytes limit. The limit includes the +# 16 bytes header. When an HyperLogLog using the sparse representation crosses +# this limit, it is converted into the dense representation. +# +# A value greater than 16000 is totally useless, since at that point the +# dense representation is more memory efficient. +# +# The suggested value is ~ 3000 in order to have the benefits of +# the space efficient encoding without slowing down too much PFADD, +# which is O(N) with the sparse encoding. The value can be raised to +# ~ 10000 when CPU is not a concern, but space is, and the data set is +# composed of many HyperLogLogs with cardinality in the 0 - 15000 range. +hll-sparse-max-bytes 3000 + +# Streams macro node max size / items. The stream data structure is a radix +# tree of big nodes that encode multiple items inside. Using this configuration +# it is possible to configure how big a single node can be in bytes, and the +# maximum number of items it may contain before switching to a new node when +# appending new stream entries. If any of the following settings are set to +# zero, the limit is ignored, so for instance it is possible to set just a +# max entires limit by setting max-bytes to 0 and max-entries to the desired +# value. +stream-node-max-bytes 4096 +stream-node-max-entries 100 + +# Active rehashing uses 1 millisecond every 100 milliseconds of CPU time in +# order to help rehashing the main Redis hash table (the one mapping top-level +# keys to values). The hash table implementation Redis uses (see dict.c) +# performs a lazy rehashing: the more operation you run into a hash table +# that is rehashing, the more rehashing "steps" are performed, so if the +# server is idle the rehashing is never complete and some more memory is used +# by the hash table. +# +# The default is to use this millisecond 10 times every second in order to +# actively rehash the main dictionaries, freeing memory when possible. +# +# If unsure: +# use "activerehashing no" if you have hard latency requirements and it is +# not a good thing in your environment that Redis can reply from time to time +# to queries with 2 milliseconds delay. +# +# use "activerehashing yes" if you don't have such hard requirements but +# want to free memory asap when possible. +activerehashing yes + +# The client output buffer limits can be used to force disconnection of clients +# that are not reading data from the server fast enough for some reason (a +# common reason is that a Pub/Sub client can't consume messages as fast as the +# publisher can produce them). +# +# The limit can be set differently for the three different classes of clients: +# +# normal -> normal clients including MONITOR clients +# replica -> replica clients +# pubsub -> clients subscribed to at least one pubsub channel or pattern +# +# The syntax of every client-output-buffer-limit directive is the following: +# +# client-output-buffer-limit +# +# A client is immediately disconnected once the hard limit is reached, or if +# the soft limit is reached and remains reached for the specified number of +# seconds (continuously). +# So for instance if the hard limit is 32 megabytes and the soft limit is +# 16 megabytes / 10 seconds, the client will get disconnected immediately +# if the size of the output buffers reach 32 megabytes, but will also get +# disconnected if the client reaches 16 megabytes and continuously overcomes +# the limit for 10 seconds. +# +# By default normal clients are not limited because they don't receive data +# without asking (in a push way), but just after a request, so only +# asynchronous clients may create a scenario where data is requested faster +# than it can read. +# +# Instead there is a default limit for pubsub and replica clients, since +# subscribers and replicas receive data in a push fashion. +# +# Both the hard or the soft limit can be disabled by setting them to zero. +client-output-buffer-limit normal 0 0 0 +client-output-buffer-limit replica 256mb 64mb 60 +client-output-buffer-limit pubsub 32mb 8mb 60 + +# Client query buffers accumulate new commands. They are limited to a fixed +# amount by default in order to avoid that a protocol desynchronization (for +# instance due to a bug in the client) will lead to unbound memory usage in +# the query buffer. However you can configure it here if you have very special +# needs, such us huge multi/exec requests or alike. +# +# client-query-buffer-limit 1gb + +# In the Redis protocol, bulk requests, that are, elements representing single +# strings, are normally limited ot 512 mb. However you can change this limit +# here. +# +# proto-max-bulk-len 512mb + +# Redis calls an internal function to perform many background tasks, like +# closing connections of clients in timeout, purging expired keys that are +# never requested, and so forth. +# +# Not all tasks are performed with the same frequency, but Redis checks for +# tasks to perform according to the specified "hz" value. +# +# By default "hz" is set to 10. Raising the value will use more CPU when +# Redis is idle, but at the same time will make Redis more responsive when +# there are many keys expiring at the same time, and timeouts may be +# handled with more precision. +# +# The range is between 1 and 500, however a value over 100 is usually not +# a good idea. Most users should use the default of 10 and raise this up to +# 100 only in environments where very low latency is required. +hz 10 + +# Normally it is useful to have an HZ value which is proportional to the +# number of clients connected. This is useful in order, for instance, to +# avoid too many clients are processed for each background task invocation +# in order to avoid latency spikes. +# +# Since the default HZ value by default is conservatively set to 10, Redis +# offers, and enables by default, the ability to use an adaptive HZ value +# which will temporary raise when there are many connected clients. +# +# When dynamic HZ is enabled, the actual configured HZ will be used as +# as a baseline, but multiples of the configured HZ value will be actually +# used as needed once more clients are connected. In this way an idle +# instance will use very little CPU time while a busy instance will be +# more responsive. +dynamic-hz yes + +# When a child rewrites the AOF file, if the following option is enabled +# the file will be fsync-ed every 32 MB of data generated. This is useful +# in order to commit the file to the disk more incrementally and avoid +# big latency spikes. +aof-rewrite-incremental-fsync yes + +# When redis saves RDB file, if the following option is enabled +# the file will be fsync-ed every 32 MB of data generated. This is useful +# in order to commit the file to the disk more incrementally and avoid +# big latency spikes. +rdb-save-incremental-fsync yes + +# Redis LFU eviction (see maxmemory setting) can be tuned. However it is a good +# idea to start with the default settings and only change them after investigating +# how to improve the performances and how the keys LFU change over time, which +# is possible to inspect via the OBJECT FREQ command. +# +# There are two tunable parameters in the Redis LFU implementation: the +# counter logarithm factor and the counter decay time. It is important to +# understand what the two parameters mean before changing them. +# +# The LFU counter is just 8 bits per key, it's maximum value is 255, so Redis +# uses a probabilistic increment with logarithmic behavior. Given the value +# of the old counter, when a key is accessed, the counter is incremented in +# this way: +# +# 1. A random number R between 0 and 1 is extracted. +# 2. A probability P is calculated as 1/(old_value*lfu_log_factor+1). +# 3. The counter is incremented only if R < P. +# +# The default lfu-log-factor is 10. This is a table of how the frequency +# counter changes with a different number of accesses with different +# logarithmic factors: +# +# +--------+------------+------------+------------+------------+------------+ +# | factor | 100 hits | 1000 hits | 100K hits | 1M hits | 10M hits | +# +--------+------------+------------+------------+------------+------------+ +# | 0 | 104 | 255 | 255 | 255 | 255 | +# +--------+------------+------------+------------+------------+------------+ +# | 1 | 18 | 49 | 255 | 255 | 255 | +# +--------+------------+------------+------------+------------+------------+ +# | 10 | 10 | 18 | 142 | 255 | 255 | +# +--------+------------+------------+------------+------------+------------+ +# | 100 | 8 | 11 | 49 | 143 | 255 | +# +--------+------------+------------+------------+------------+------------+ +# +# NOTE: The above table was obtained by running the following commands: +# +# redis-benchmark -n 1000000 incr foo +# redis-cli object freq foo +# +# NOTE 2: The counter initial value is 5 in order to give new objects a chance +# to accumulate hits. +# +# The counter decay time is the time, in minutes, that must elapse in order +# for the key counter to be divided by two (or decremented if it has a value +# less <= 10). +# +# The default value for the lfu-decay-time is 1. A Special value of 0 means to +# decay the counter every time it happens to be scanned. +# +# lfu-log-factor 10 +# lfu-decay-time 1 + +################################## INCLUDES ################################### + +# Include one or more other config files here. This is useful if you +# have a standard template that goes to all Redis server but also need +# to customize a few per-server settings. Include files can include +# other files, so use this wisely. +# +# include /path/to/local.conf +# include /path/to/other.conf diff --git a/apps/api/.env.example b/apps/api/.env.example index 4a487e5..1bf8723 100644 --- a/apps/api/.env.example +++ b/apps/api/.env.example @@ -5,7 +5,7 @@ API_PORT=8000 DEBUG=true # Database -DATABASE_URL=postgresql+asyncpg://postgres:postgres@localhost:5432/translator +DATABASE_URL=mysql+aiomysql://root:root@localhost:3306/translator # Redis REDIS_URL=redis://localhost:6379/0 diff --git a/apps/api/app/api/admin.py b/apps/api/app/api/admin.py index ef7770e..41dcbfc 100644 --- a/apps/api/app/api/admin.py +++ b/apps/api/app/api/admin.py @@ -1,6 +1,7 @@ from fastapi import APIRouter, HTTPException, Depends, Header from sqlalchemy import select from sqlalchemy.ext.asyncio import AsyncSession +from pydantic import BaseModel from ..core import get_db from ..models import Admin @@ -11,7 +12,6 @@ router = APIRouter(prefix="/api/v1/admin", tags=["admin"]) async def get_current_admin( authorization: str = Header(None), - db: AsyncSession = Depends(get_db), ): if not authorization or not authorization.startswith("Bearer "): raise HTTPException(status_code=401, detail="未授权") @@ -22,15 +22,52 @@ async def get_current_admin( return payload +class AdminLoginRequest(BaseModel): + username: str + password: str + + +class AdminChangePasswordRequest(BaseModel): + old_password: str + new_password: str + + @router.post("/login") async def login( - username: str, - password: str, + data: AdminLoginRequest, db: AsyncSession = Depends(get_db), ): - result = await db.execute(select(Admin).where(Admin.username == username)) + result = await db.execute(select(Admin).where(Admin.username == data.username)) admin = result.scalar_one_or_none() - if not admin or not verify_password(password, admin.password_hash): + if not admin or not verify_password(data.password, admin.password_hash): raise HTTPException(status_code=401, detail="用户名或密码错误") token = create_token({"sub": admin.username, "id": admin.id}) - return {"token": token} + return {"token": token, "username": admin.username} + + +@router.get("/me") +async def me(payload: dict = Depends(get_current_admin)): + return {"id": payload.get("id"), "username": payload.get("sub"), "exp": payload.get("exp")} + + +@router.post("/change-password") +async def change_password( + data: AdminChangePasswordRequest, + payload: dict = Depends(get_current_admin), + db: AsyncSession = Depends(get_db), +): + admin_id = payload.get("id") + if not admin_id: + raise HTTPException(status_code=401, detail="未授权") + + result = await db.execute(select(Admin).where(Admin.id == admin_id)) + admin = result.scalar_one_or_none() + if not admin or not verify_password(data.old_password, admin.password_hash): + raise HTTPException(status_code=400, detail="原密码错误") + + if len(data.new_password) < 8: + raise HTTPException(status_code=400, detail="新密码至少 8 位") + + admin.password_hash = hash_password(data.new_password) + await db.commit() + return {"success": True} diff --git a/apps/api/app/api/ai_provider.py b/apps/api/app/api/ai_provider.py index 0dcde72..0d0643b 100644 --- a/apps/api/app/api/ai_provider.py +++ b/apps/api/app/api/ai_provider.py @@ -1,7 +1,9 @@ from fastapi import APIRouter, HTTPException, Depends from sqlalchemy import select from sqlalchemy.ext.asyncio import AsyncSession -from pydantic import BaseModel +from pydantic import BaseModel, ConfigDict +import time +import httpx from ..core import get_db from ..models import AIProvider @@ -11,14 +13,19 @@ router = APIRouter(prefix="/api/v1/admin/providers", tags=["ai-providers"]) class ProviderCreate(BaseModel): + model_config = ConfigDict(protected_namespaces=()) + name: str model_id: str base_url: str | None = None api_key: str + is_active: bool = True is_default: bool = False class ProviderUpdate(BaseModel): + model_config = ConfigDict(protected_namespaces=()) + name: str | None = None model_id: str | None = None base_url: str | None = None @@ -106,3 +113,43 @@ async def delete_provider( await db.delete(provider) await db.commit() return {"success": True} + + +@router.post("/{provider_id}/test") +async def test_provider( + provider_id: int, + db: AsyncSession = Depends(get_db), + _: dict = Depends(get_current_admin), +): + result = await db.execute(select(AIProvider).where(AIProvider.id == provider_id)) + provider = result.scalar_one_or_none() + if not provider: + raise HTTPException(status_code=404, detail="Provider 不存在") + + base_url = (provider.base_url or "https://api.openai.com/v1").rstrip("/") + url = f"{base_url}/chat/completions" + + start = time.perf_counter() + try: + async with httpx.AsyncClient(timeout=10.0) as client: + res = await client.post( + url, + headers={"Authorization": f"Bearer {provider.api_key}"}, + json={ + "model": provider.model_id, + "messages": [{"role": "user", "content": "ping"}], + "temperature": 0, + "max_tokens": 1, + }, + ) + res.raise_for_status() + except httpx.HTTPStatusError as e: + detail = (e.response.text or "").strip() + if len(detail) > 200: + detail = detail[:200] + "..." + raise HTTPException(status_code=400, detail=f"测试失败:{detail or e.response.reason_phrase}") + except Exception as e: + raise HTTPException(status_code=400, detail=f"测试失败:{str(e)}") + + latency_ms = int((time.perf_counter() - start) * 1000) + return {"ok": True, "latency_ms": latency_ms} diff --git a/apps/api/app/api/translate.py b/apps/api/app/api/translate.py index 15d4391..cd02328 100644 --- a/apps/api/app/api/translate.py +++ b/apps/api/app/api/translate.py @@ -1,3 +1,4 @@ +import asyncio import json from fastapi import APIRouter, HTTPException, Request from fastapi.responses import StreamingResponse @@ -34,10 +35,13 @@ async def translate(request: Request, payload: TranslateRequest): cached=True, ) + source_lang_display = payload.source_lang_name or payload.source_lang + target_lang_display = payload.target_lang_name or payload.target_lang + translation = await llm_service.translate( payload.source_text, - payload.source_lang, - payload.target_lang, + source_lang_display, + target_lang_display, payload.style.value, ) @@ -71,34 +75,59 @@ async def translate_stream(request: Request, payload: TranslateRequest): cached = await cache_service.get(cache_key) + source_lang_display = payload.source_lang_name or payload.source_lang + target_lang_display = payload.target_lang_name or payload.target_lang + + async def _safe_cache_set(translation: str): + try: + await cache_service.set(cache_key, { + "source_lang": payload.source_lang, + "translation": translation, + }) + except Exception: + # 缓存写入失败不影响响应 + pass + + def _is_cancelled(exc: BaseException) -> bool: + # Python 3.11: CancelledError & BaseExceptionGroup are BaseException, not Exception. + if isinstance(exc, asyncio.CancelledError): + return True + if isinstance(exc, BaseExceptionGroup): + return all(_is_cancelled(e) for e in exc.exceptions) + return False + async def generate(): - if cached: - meta = {"source_lang": payload.source_lang, "target_lang": payload.target_lang, "cached": True} - yield f"event: meta\ndata: {json.dumps(meta)}\n\n" - yield f"event: chunk\ndata: {json.dumps({'delta': cached['translation']})}\n\n" - done = {"translation": cached["translation"]} - yield f"event: done\ndata: {json.dumps(done)}\n\n" - return - - meta = {"source_lang": payload.source_lang, "target_lang": payload.target_lang, "cached": False} - yield f"event: meta\ndata: {json.dumps(meta)}\n\n" - full_translation = "" - async for chunk in llm_service.translate_stream( - payload.source_text, - payload.source_lang, - payload.target_lang, - payload.style.value, - ): - full_translation += chunk - yield f"event: chunk\ndata: {json.dumps({'delta': chunk})}\n\n" + try: + if cached: + meta = {"source_lang": payload.source_lang, "target_lang": payload.target_lang, "cached": True} + yield f"event: meta\ndata: {json.dumps(meta)}\n\n" + yield f"event: chunk\ndata: {json.dumps({'delta': cached['translation']})}\n\n" + yield f"event: done\ndata: {json.dumps({'translation': cached['translation']})}\n\n" + return - await cache_service.set(cache_key, { - "source_lang": payload.source_lang, - "translation": full_translation, - }) + meta = {"source_lang": payload.source_lang, "target_lang": payload.target_lang, "cached": False} + yield f"event: meta\ndata: {json.dumps(meta)}\n\n" - done = {"translation": full_translation} - yield f"event: done\ndata: {json.dumps(done)}\n\n" + async for chunk in llm_service.translate_stream( + payload.source_text, + source_lang_display, + target_lang_display, + payload.style.value, + ): + full_translation += chunk + yield f"event: chunk\ndata: {json.dumps({'delta': chunk})}\n\n" + + # 缓存写入放到后台,避免影响流式响应完成 + asyncio.create_task(_safe_cache_set(full_translation)) + yield f"event: done\ndata: {json.dumps({'translation': full_translation})}\n\n" + except BaseException as e: + if _is_cancelled(e): + # 客户端断开或任务被取消时,直接结束生成器,避免打断 chunked 响应收尾。 + task = asyncio.current_task() + if task: + task.uncancel() + return + yield f"event: error\ndata: {json.dumps({'error': str(e)})}\n\n" return StreamingResponse(generate(), media_type="text/event-stream") diff --git a/apps/api/app/core/config.py b/apps/api/app/core/config.py index e2ee0d2..2406a87 100644 --- a/apps/api/app/core/config.py +++ b/apps/api/app/core/config.py @@ -10,7 +10,7 @@ class Settings(BaseSettings): debug: bool = True # Database - database_url: str = "postgresql+asyncpg://user:pass@db:5432/app" + database_url: str = "mysql+aiomysql://user:pass@db:3306/app" # Redis redis_url: str = "redis://redis:6379/0" diff --git a/apps/api/app/main.py b/apps/api/app/main.py index a463d02..9cbe4e6 100644 --- a/apps/api/app/main.py +++ b/apps/api/app/main.py @@ -2,7 +2,7 @@ from contextlib import asynccontextmanager from fastapi import FastAPI from fastapi.middleware.cors import CORSMiddleware -from .core import get_settings, logger +from .core import get_settings, logger, engine from .api import translate_router, admin_router, provider_router, stats_router from .services import cache_service, rate_limit_service, llm_service, stats_service @@ -22,6 +22,10 @@ async def lifespan(app: FastAPI): await rate_limit_service.disconnect() await llm_service.disconnect() await stats_service.disconnect() + try: + await engine.dispose() + except Exception: + pass app = FastAPI( diff --git a/apps/api/app/schemas/response.py b/apps/api/app/schemas/response.py index 02c3ee3..64f9b5f 100644 --- a/apps/api/app/schemas/response.py +++ b/apps/api/app/schemas/response.py @@ -1,3 +1,6 @@ +from pydantic import BaseModel + + class TranslateResponse(BaseModel): source_lang: str target_lang: str diff --git a/apps/api/app/schemas/translate.py b/apps/api/app/schemas/translate.py index 673ea94..2d14e13 100644 --- a/apps/api/app/schemas/translate.py +++ b/apps/api/app/schemas/translate.py @@ -11,7 +11,9 @@ class TranslationStyle(str, Enum): class TranslateRequest(BaseModel): source_text: str = Field(..., min_length=1, max_length=10000) source_lang: str = Field(default="auto", max_length=10) + source_lang_name: str | None = Field(default=None, max_length=50) target_lang: str = Field(..., max_length=10) + target_lang_name: str | None = Field(default=None, max_length=50) style: TranslationStyle = TranslationStyle.literal glossary_id: str | None = None format: str = "text" diff --git a/apps/api/app/services/cache.py b/apps/api/app/services/cache.py index 2d12d68..cf860e5 100644 --- a/apps/api/app/services/cache.py +++ b/apps/api/app/services/cache.py @@ -1,3 +1,4 @@ +import asyncio import hashlib import json import redis.asyncio as redis @@ -11,7 +12,11 @@ class CacheService: self.redis: redis.Redis | None = None async def connect(self): - self.redis = redis.from_url(settings.redis_url) + try: + self.redis = redis.from_url(settings.redis_url) + await self.redis.ping() + except Exception: + self.redis = None async def disconnect(self): if self.redis: @@ -38,7 +43,12 @@ class CacheService: async def get(self, key: str) -> dict | None: if not self.redis: return None - data = await self.redis.get(key) + try: + data = await self.redis.get(key) + except asyncio.CancelledError: + return None + except Exception: + return None if data: return json.loads(data) return None @@ -47,7 +57,12 @@ class CacheService: if not self.redis: return ttl = ttl or settings.cache_ttl_seconds - await self.redis.set(key, json.dumps(value), ex=ttl) + try: + await self.redis.set(key, json.dumps(value), ex=ttl) + except asyncio.CancelledError: + return + except Exception: + return cache_service = CacheService() diff --git a/apps/api/app/services/llm.py b/apps/api/app/services/llm.py index 1faed7b..568939d 100644 --- a/apps/api/app/services/llm.py +++ b/apps/api/app/services/llm.py @@ -1,6 +1,11 @@ import httpx +import json from typing import AsyncGenerator +from sqlalchemy import select +from sqlalchemy.ext.asyncio import AsyncSession from ..core import get_settings +from ..core.database import AsyncSessionLocal +from ..models import AIProvider settings = get_settings() @@ -16,6 +21,29 @@ class LLMService: if self.client: await self.client.aclose() + async def _get_provider(self) -> dict: + """从数据库获取默认的 AI Provider 配置""" + async with AsyncSessionLocal() as session: + result = await session.execute( + select(AIProvider).where( + AIProvider.is_active == True, + AIProvider.is_default == True + ) + ) + provider = result.scalar_one_or_none() + if provider: + return { + "api_key": provider.api_key, + "base_url": provider.base_url or "https://api.openai.com/v1", + "model": provider.model_id, + } + # 回退到环境变量配置 + return { + "api_key": settings.llm_api_key, + "base_url": settings.llm_base_url or "https://api.openai.com/v1", + "model": settings.llm_model, + } + def _build_prompt( self, source_text: str, @@ -44,14 +72,14 @@ class LLMService: if not self.client: raise RuntimeError("LLM client not initialized") + provider = await self._get_provider() messages = self._build_prompt(source_text, source_lang, target_lang, style) - base_url = settings.llm_base_url or "https://api.openai.com/v1" response = await self.client.post( - f"{base_url}/chat/completions", - headers={"Authorization": f"Bearer {settings.llm_api_key}"}, + f"{provider['base_url']}/chat/completions", + headers={"Authorization": f"Bearer {provider['api_key']}"}, json={ - "model": settings.llm_model, + "model": provider["model"], "messages": messages, "temperature": settings.default_temperature, }, @@ -70,15 +98,15 @@ class LLMService: if not self.client: raise RuntimeError("LLM client not initialized") + provider = await self._get_provider() messages = self._build_prompt(source_text, source_lang, target_lang, style) - base_url = settings.llm_base_url or "https://api.openai.com/v1" async with self.client.stream( "POST", - f"{base_url}/chat/completions", - headers={"Authorization": f"Bearer {settings.llm_api_key}"}, + f"{provider['base_url']}/chat/completions", + headers={"Authorization": f"Bearer {provider['api_key']}"}, json={ - "model": settings.llm_model, + "model": provider["model"], "messages": messages, "temperature": settings.default_temperature, "stream": True, @@ -89,7 +117,6 @@ class LLMService: data = line[6:] if data == "[DONE]": break - import json chunk = json.loads(data) delta = chunk["choices"][0].get("delta", {}) if "content" in delta: diff --git a/apps/api/app/services/rate_limit.py b/apps/api/app/services/rate_limit.py index ed305ab..a73db73 100644 --- a/apps/api/app/services/rate_limit.py +++ b/apps/api/app/services/rate_limit.py @@ -1,3 +1,4 @@ +import asyncio import time import redis.asyncio as redis from ..core import get_settings @@ -10,7 +11,11 @@ class RateLimitService: self.redis: redis.Redis | None = None async def connect(self): - self.redis = redis.from_url(settings.redis_url) + try: + self.redis = redis.from_url(settings.redis_url) + await self.redis.ping() + except Exception: + self.redis = None async def disconnect(self): if self.redis: @@ -23,9 +28,14 @@ class RateLimitService: now = int(time.time()) window_key = f"rl:{key}:{now // 60}" - count = await self.redis.incr(window_key) - if count == 1: - await self.redis.expire(window_key, 60) + try: + count = await self.redis.incr(window_key) + if count == 1: + await self.redis.expire(window_key, 60) + except asyncio.CancelledError: + return True + except Exception: + return True return count <= limit diff --git a/apps/api/app/services/stats.py b/apps/api/app/services/stats.py index 687219b..4b2c86f 100644 --- a/apps/api/app/services/stats.py +++ b/apps/api/app/services/stats.py @@ -1,3 +1,4 @@ +import asyncio import json from datetime import datetime import redis.asyncio as redis @@ -30,21 +31,26 @@ class StatsService: ): if not self.redis: return - now = datetime.utcnow() - date = now.strftime("%Y-%m-%d") - hour = now.hour - key = self._get_key(provider_id, date, hour) + try: + now = datetime.utcnow() + date = now.strftime("%Y-%m-%d") + hour = now.hour + key = self._get_key(provider_id, date, hour) - pipe = self.redis.pipeline() - pipe.hincrby(key, "request_count", 1) - pipe.hincrby(key, "input_tokens", input_tokens) - pipe.hincrby(key, "output_tokens", output_tokens) - if cached: - pipe.hincrby(key, "cached_count", 1) - if error: - pipe.hincrby(key, "error_count", 1) - pipe.expire(key, 86400 * 30) - await pipe.execute() + pipe = self.redis.pipeline() + pipe.hincrby(key, "request_count", 1) + pipe.hincrby(key, "input_tokens", input_tokens) + pipe.hincrby(key, "output_tokens", output_tokens) + if cached: + pipe.hincrby(key, "cached_count", 1) + if error: + pipe.hincrby(key, "error_count", 1) + pipe.expire(key, 86400 * 30) + await pipe.execute() + except asyncio.CancelledError: + return + except Exception: + return async def get_stats(self, provider_id: int, date: str) -> dict: if not self.redis: @@ -61,7 +67,12 @@ class StatsService: for hour in range(24): key = self._get_key(provider_id, date, hour) - data = await self.redis.hgetall(key) + try: + data = await self.redis.hgetall(key) + except asyncio.CancelledError: + return result + except Exception: + data = {} hourly = { "hour": hour, "request_count": int(data.get(b"request_count", 0)), @@ -79,27 +90,37 @@ class StatsService: async def get_rpm_tpm(self, provider_id: int) -> dict: if not self.redis: return {"rpm": 0, "tpm": 0} - now = datetime.utcnow() - minute_key = f"rpm:{provider_id}:{now.strftime('%Y-%m-%d-%H-%M')}" - rpm = int(await self.redis.get(minute_key) or 0) + try: + now = datetime.utcnow() + minute_key = f"rpm:{provider_id}:{now.strftime('%Y-%m-%d-%H-%M')}" + rpm = int(await self.redis.get(minute_key) or 0) - tpm_key = f"tpm:{provider_id}:{now.strftime('%Y-%m-%d-%H-%M')}" - tpm = int(await self.redis.get(tpm_key) or 0) - return {"rpm": rpm, "tpm": tpm} + tpm_key = f"tpm:{provider_id}:{now.strftime('%Y-%m-%d-%H-%M')}" + tpm = int(await self.redis.get(tpm_key) or 0) + return {"rpm": rpm, "tpm": tpm} + except asyncio.CancelledError: + return {"rpm": 0, "tpm": 0} + except Exception: + return {"rpm": 0, "tpm": 0} async def incr_rpm_tpm(self, provider_id: int, tokens: int): if not self.redis: return - now = datetime.utcnow() - minute_key = f"rpm:{provider_id}:{now.strftime('%Y-%m-%d-%H-%M')}" - tpm_key = f"tpm:{provider_id}:{now.strftime('%Y-%m-%d-%H-%M')}" + try: + now = datetime.utcnow() + minute_key = f"rpm:{provider_id}:{now.strftime('%Y-%m-%d-%H-%M')}" + tpm_key = f"tpm:{provider_id}:{now.strftime('%Y-%m-%d-%H-%M')}" - pipe = self.redis.pipeline() - pipe.incr(minute_key) - pipe.expire(minute_key, 120) - pipe.incrby(tpm_key, tokens) - pipe.expire(tpm_key, 120) - await pipe.execute() + pipe = self.redis.pipeline() + pipe.incr(minute_key) + pipe.expire(minute_key, 120) + pipe.incrby(tpm_key, tokens) + pipe.expire(tpm_key, 120) + await pipe.execute() + except asyncio.CancelledError: + return + except Exception: + return stats_service = StatsService() diff --git a/apps/api/pyproject.toml b/apps/api/pyproject.toml index 119fa74..ac5f882 100644 --- a/apps/api/pyproject.toml +++ b/apps/api/pyproject.toml @@ -9,7 +9,7 @@ dependencies = [ "pydantic>=2.5.0", "pydantic-settings>=2.1.0", "redis>=5.0.0", - "asyncpg>=0.29.0", + "aiomysql>=0.2.0", "sqlalchemy[asyncio]>=2.0.0", "httpx>=0.26.0", "python-jose[cryptography]>=3.3.0", @@ -28,6 +28,9 @@ dev = [ requires = ["hatchling"] build-backend = "hatchling.build" +[tool.hatch.build.targets.wheel] +packages = ["app"] + [tool.ruff] line-length = 100 target-version = "py311" diff --git a/apps/web/Dockerfile b/apps/web/Dockerfile index 14d9192..7de06ac 100644 --- a/apps/web/Dockerfile +++ b/apps/web/Dockerfile @@ -12,8 +12,8 @@ FROM node:20-alpine AS runner WORKDIR /app -COPY --from=builder /app/.next/standalone ./ -COPY --from=builder /app/.next/static ./.next/static +COPY --from=builder /app/.next-prod/standalone ./ +COPY --from=builder /app/.next-prod/static ./.next/static COPY --from=builder /app/public ./public EXPOSE 3000 diff --git a/apps/web/app/admin/layout.tsx b/apps/web/app/admin/layout.tsx index d7a19dd..003c141 100644 --- a/apps/web/app/admin/layout.tsx +++ b/apps/web/app/admin/layout.tsx @@ -1,7 +1,15 @@ 'use client' import Link from 'next/link' -import { useRouter } from 'next/navigation' +import { usePathname, useRouter } from 'next/navigation' +import { useEffect, useMemo, useState } from 'react' +import { BarChart3, Bot, LayoutDashboard, LogOut, Settings } from 'lucide-react' + +import { Button } from '@/components/ui/button' +import { cn } from '@/lib/utils' +import { ADMIN_UNAUTHORIZED_EVENT } from '@/lib/admin-api' + +const API_BASE = process.env.NEXT_PUBLIC_API_BASE_URL || 'http://localhost:8000' export default function AdminLayout({ children, @@ -9,43 +17,166 @@ export default function AdminLayout({ children: React.ReactNode }) { const router = useRouter() + const pathname = usePathname() + const [authChecked, setAuthChecked] = useState(false) + const [adminName, setAdminName] = useState('') + + const navItems = useMemo( + () => [ + { href: '/admin', label: '概览', icon: LayoutDashboard }, + { href: '/admin/providers', label: 'AI 配置', icon: Bot }, + { href: '/admin/stats', label: '统计', icon: BarChart3 }, + { href: '/admin/settings', label: '设置', icon: Settings }, + ], + [] + ) + + const getToken = () => localStorage.getItem('admin_token') || '' + + const fetchMe = async () => { + const token = getToken() + if (!token) return + + try { + const res = await fetch(`${API_BASE}/api/v1/admin/me`, { + headers: { Authorization: `Bearer ${token}` }, + }) + if (res.status === 401) throw new Error('unauthorized') + if (!res.ok) return + const data = await res.json() + setAdminName(data.username || data.sub || '') + } catch { + localStorage.removeItem('admin_token') + router.replace('/login') + } + } + + useEffect(() => { + const token = getToken() + if (!token) { + router.replace('/login') + return + } + setAuthChecked(true) + fetchMe() + // eslint-disable-next-line react-hooks/exhaustive-deps + }, []) + + useEffect(() => { + const onUnauthorized = () => { + localStorage.removeItem('admin_token') + router.replace('/login') + } + window.addEventListener(ADMIN_UNAUTHORIZED_EVENT, onUnauthorized) + return () => window.removeEventListener(ADMIN_UNAUTHORIZED_EVENT, onUnauthorized) + }, [router]) const handleLogout = () => { localStorage.removeItem('admin_token') - router.push('/login') + router.replace('/login') + } + + if (!authChecked) { + return ( +
+
加载中...
+
+ ) } return ( -
- -
- {children} -
+
) } diff --git a/apps/web/app/admin/page.tsx b/apps/web/app/admin/page.tsx index 3501e23..bde51d3 100644 --- a/apps/web/app/admin/page.tsx +++ b/apps/web/app/admin/page.tsx @@ -1,23 +1,375 @@ 'use client' +import { useEffect, useMemo, useState } from 'react' +import Link from 'next/link' +import { useRouter } from 'next/navigation' +import { Activity, BarChart3, Bot, RefreshCcw } from 'lucide-react' + +import { Badge } from '@/components/ui/badge' +import { Button } from '@/components/ui/button' +import { + Card, + CardContent, + CardDescription, + CardHeader, + CardTitle, +} from '@/components/ui/card' +import { + Select, + SelectContent, + SelectItem, + SelectTrigger, + SelectValue, +} from '@/components/ui/select' +import { + Table, + TableBody, + TableCell, + TableHead, + TableHeader, + TableRow, +} from '@/components/ui/table' +import { AdminUnauthorizedError, API_BASE, adminFetchJson } from '@/lib/admin-api' + +interface Provider { + id: number + name: string + model_id: string + base_url: string | null + is_active: boolean + is_default: boolean +} + +interface HourlyStat { + hour: number + request_count: number + input_tokens: number + output_tokens: number + cached_count: number + error_count: number +} + +interface DailyStats { + date: string + request_count: number + input_tokens: number + output_tokens: number + cached_count: number + error_count: number + hourly: HourlyStat[] +} + +interface RealtimeStats { + rpm: number + tpm: number +} + +function formatNumber(value: number) { + return new Intl.NumberFormat('zh-CN').format(value) +} + +function formatPercent(value: number) { + return `${(value * 100).toFixed(1)}%` +} + export default function AdminPage() { + const router = useRouter() + const [providers, setProviders] = useState([]) + const [providerId, setProviderId] = useState('') + const [daily, setDaily] = useState(null) + const [realtime, setRealtime] = useState({ rpm: 0, tpm: 0 }) + const [healthOk, setHealthOk] = useState(null) + const [isLoading, setIsLoading] = useState(false) + const [error, setError] = useState('') + + const selectedProvider = useMemo( + () => providers.find((p) => String(p.id) === providerId) || null, + [providers, providerId] + ) + + const cacheHitRate = useMemo(() => { + if (!daily || daily.request_count <= 0) return 0 + return daily.cached_count / daily.request_count + }, [daily]) + + const errorRate = useMemo(() => { + if (!daily || daily.request_count <= 0) return 0 + return daily.error_count / daily.request_count + }, [daily]) + + const totalTokens = useMemo(() => { + if (!daily) return 0 + return daily.input_tokens + daily.output_tokens + }, [daily]) + + const fetchProviders = async () => { + setIsLoading(true) + setError('') + try { + const data = await adminFetchJson('/api/v1/admin/providers') + setProviders(data) + const defaultOne = data.find((p) => p.is_default) || data[0] || null + if (defaultOne) setProviderId(String(defaultOne.id)) + } catch (err: any) { + if (err instanceof AdminUnauthorizedError) { + router.replace('/login') + return + } + setError(err?.message || '加载失败') + } finally { + setIsLoading(false) + } + } + + const fetchDaily = async (id: string) => { + try { + const data = await adminFetchJson(`/api/v1/admin/stats/daily/${id}`) + setDaily(data) + } catch (err: any) { + if (err instanceof AdminUnauthorizedError) { + router.replace('/login') + return + } + setError(err?.message || '加载统计失败') + } + } + + const fetchRealtime = async (id: string) => { + try { + const data = await adminFetchJson(`/api/v1/admin/stats/realtime/${id}`) + setRealtime(data) + } catch (err: any) { + if (err instanceof AdminUnauthorizedError) { + router.replace('/login') + return + } + } + } + + const fetchHealth = async () => { + try { + const res = await fetch(`${API_BASE}/health`) + setHealthOk(res.ok) + } catch { + setHealthOk(false) + } + } + + useEffect(() => { + fetchProviders() + fetchHealth() + // eslint-disable-next-line react-hooks/exhaustive-deps + }, []) + + useEffect(() => { + if (!providerId) return + fetchDaily(providerId) + fetchRealtime(providerId) + const timer = setInterval(() => fetchRealtime(providerId), 5000) + return () => clearInterval(timer) + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [providerId]) + return ( -
-

管理后台概览

-
-
-

今日请求

-

--

+
+
+
+

概览

+

+ 关键指标、Provider 状态与系统健康检查 +

-
-

今日 Token

-

--

-
-
-

缓存命中率

-

--

+
+ + + +
+ + {error && ( +
+ {error} +
+ )} + + + +
+ 当前 Provider + 选择一个 Provider 查看实时与今日指标 +
+
+ +
+
+ +
+ API 健康: + {healthOk === null ? ( + 未知 + ) : healthOk ? ( + OK + ) : ( + 异常 + )} + {selectedProvider && ( + <> + 状态: + {selectedProvider.is_active ? ( + 启用 + ) : ( + + 禁用 + + )} + {selectedProvider.is_default && 默认} + + )} +
+ +
+ + + RPM(每分钟请求) + {formatNumber(realtime.rpm)} + + + + + TPM(每分钟 Token) + {formatNumber(realtime.tpm)} + + + + + 今日请求 + + {daily ? formatNumber(daily.request_count) : '--'} + + + + + + 今日 Token + + {daily ? formatNumber(totalTokens) : '--'} + + + +
+ +
+ + + 缓存命中率 + + {daily ? formatPercent(cacheHitRate) : '--'} + + + + 命中 {daily ? formatNumber(daily.cached_count) : '--'} 次 + + + + + 错误率 + + {daily ? formatPercent(errorRate) : '--'} + + + + 错误 {daily ? formatNumber(daily.error_count) : '--'} 次 + + + + + 输入/输出 Token + + {daily ? formatNumber(daily.input_tokens) : '--'} / {daily ? formatNumber(daily.output_tokens) : '--'} + + + +
+
+
+ + + + Provider 列表 + 快速查看默认与启用状态 + + +
+ + + + 名称 + 模型 + 状态 + + + + {providers.length === 0 ? ( + + + 暂无 Provider,请先去“AI 配置”添加。 + + + ) : ( + providers.map((p) => ( + + +
+ {p.name} + {p.is_default && 默认} +
+
+ {p.model_id} + + {p.is_active ? ( + 启用 + ) : ( + + 禁用 + + )} + +
+ )) + )} +
+
+
+
+
) } diff --git a/apps/web/app/admin/providers/page.tsx b/apps/web/app/admin/providers/page.tsx index 9153953..4b1bf03 100644 --- a/apps/web/app/admin/providers/page.tsx +++ b/apps/web/app/admin/providers/page.tsx @@ -1,8 +1,31 @@ 'use client' -import { useState, useEffect } from 'react' +import { useEffect, useMemo, useState } from 'react' +import { useRouter } from 'next/navigation' +import { Pencil, Plus, RefreshCcw, Star, Trash2, Wand2, ZapOff } from 'lucide-react' -const API_BASE = process.env.NEXT_PUBLIC_API_BASE_URL || 'http://localhost:8000' +import { Button } from '@/components/ui/button' +import { + Card, + CardContent, + CardDescription, + CardFooter, + CardHeader, + CardTitle, +} from '@/components/ui/card' +import { Input } from '@/components/ui/input' +import { Label } from '@/components/ui/label' +import { Badge } from '@/components/ui/badge' +import { + Table, + TableBody, + TableCell, + TableHead, + TableHeader, + TableRow, +} from '@/components/ui/table' +import { Textarea } from '@/components/ui/textarea' +import { AdminUnauthorizedError, adminFetchJson } from '@/lib/admin-api' interface Provider { id: number @@ -11,28 +34,51 @@ interface Provider { base_url: string | null is_active: boolean is_default: boolean + created_at?: string } export default function ProvidersPage() { + const router = useRouter() + const [providers, setProviders] = useState([]) - const [showForm, setShowForm] = useState(false) - const [editId, setEditId] = useState(null) + const [query, setQuery] = useState('') + const [onlyActive, setOnlyActive] = useState(false) + const [isLoading, setIsLoading] = useState(false) + const [error, setError] = useState('') + + const [dialogOpen, setDialogOpen] = useState(false) + const [editing, setEditing] = useState(null) + const [isSaving, setIsSaving] = useState(false) + + const [testResult, setTestResult] = useState<{ + ok: boolean + latency_ms?: number + message?: string + } | null>(null) + const [form, setForm] = useState({ name: '', model_id: '', base_url: '', api_key: '', + is_active: true, is_default: false, }) - const getToken = () => localStorage.getItem('admin_token') || '' - const fetchProviders = async () => { - const res = await fetch(`${API_BASE}/api/v1/admin/providers`, { - headers: { Authorization: `Bearer ${getToken()}` }, - }) - if (res.ok) { - setProviders(await res.json()) + setIsLoading(true) + setError('') + try { + const data = await adminFetchJson('/api/v1/admin/providers') + setProviders(data) + } catch (err: any) { + if (err instanceof AdminUnauthorizedError) { + router.replace('/login') + return + } + setError(err?.message || '加载失败') + } finally { + setIsLoading(false) } } @@ -40,166 +86,437 @@ export default function ProvidersPage() { fetchProviders() }, []) - const handleSubmit = async () => { - const url = editId - ? `${API_BASE}/api/v1/admin/providers/${editId}` - : `${API_BASE}/api/v1/admin/providers` - const method = editId ? 'PUT' : 'POST' - - await fetch(url, { - method, - headers: { - 'Content-Type': 'application/json', - Authorization: `Bearer ${getToken()}`, - }, - body: JSON.stringify(form), + const filteredProviders = useMemo(() => { + const q = query.trim().toLowerCase() + return providers.filter((p) => { + if (onlyActive && !p.is_active) return false + if (!q) return true + return ( + p.name.toLowerCase().includes(q) || + p.model_id.toLowerCase().includes(q) || + (p.base_url || '').toLowerCase().includes(q) + ) }) + }, [providers, query, onlyActive]) - setShowForm(false) - setEditId(null) - setForm({ name: '', model_id: '', base_url: '', api_key: '', is_default: false }) - fetchProviders() + const openCreate = () => { + setEditing(null) + setTestResult(null) + setForm({ + name: '', + model_id: '', + base_url: '', + api_key: '', + is_active: true, + is_default: false, + }) + setDialogOpen(true) } - const handleDelete = async (id: number) => { - if (!confirm('确定删除?')) return - await fetch(`${API_BASE}/api/v1/admin/providers/${id}`, { - method: 'DELETE', - headers: { Authorization: `Bearer ${getToken()}` }, + const openEdit = (provider: Provider) => { + setEditing(provider) + setTestResult(null) + setForm({ + name: provider.name, + model_id: provider.model_id, + base_url: provider.base_url || '', + api_key: '', + is_active: provider.is_active, + is_default: provider.is_default, }) - fetchProviders() + setDialogOpen(true) + } + + const handleSubmit = async () => { + setIsSaving(true) + setError('') + + try { + if (editing) { + const payload: Record = { + name: form.name, + model_id: form.model_id, + base_url: form.base_url.trim() ? form.base_url.trim() : null, + is_active: form.is_active, + is_default: form.is_default, + } + if (form.api_key.trim()) payload.api_key = form.api_key.trim() + + await adminFetchJson(`/api/v1/admin/providers/${editing.id}`, { + method: 'PUT', + body: JSON.stringify(payload), + }) + } else { + await adminFetchJson(`/api/v1/admin/providers`, { + method: 'POST', + body: JSON.stringify({ + name: form.name, + model_id: form.model_id, + base_url: form.base_url.trim() ? form.base_url.trim() : null, + api_key: form.api_key.trim(), + is_active: form.is_active, + is_default: form.is_default, + }), + }) + } + + setDialogOpen(false) + setEditing(null) + setForm({ + name: '', + model_id: '', + base_url: '', + api_key: '', + is_active: true, + is_default: false, + }) + await fetchProviders() + } catch (err: any) { + if (err instanceof AdminUnauthorizedError) { + router.replace('/login') + return + } + setError(err?.message || '保存失败') + } finally { + setIsSaving(false) + } + } + + const handleDelete = async (provider: Provider) => { + if (!confirm('确定删除?')) return + setError('') + + try { + await adminFetchJson(`/api/v1/admin/providers/${provider.id}`, { method: 'DELETE' }) + await fetchProviders() + } catch (err: any) { + if (err instanceof AdminUnauthorizedError) { + router.replace('/login') + return + } + setError(err?.message || '删除失败') + } + } + + const setDefault = async (provider: Provider) => { + setError('') + try { + await adminFetchJson(`/api/v1/admin/providers/${provider.id}`, { + method: 'PUT', + body: JSON.stringify({ is_default: true }), + }) + await fetchProviders() + } catch (err: any) { + if (err instanceof AdminUnauthorizedError) { + router.replace('/login') + return + } + setError(err?.message || '操作失败') + } + } + + const toggleActive = async (provider: Provider) => { + setError('') + try { + await adminFetchJson(`/api/v1/admin/providers/${provider.id}`, { + method: 'PUT', + body: JSON.stringify({ is_active: !provider.is_active }), + }) + await fetchProviders() + } catch (err: any) { + if (err instanceof AdminUnauthorizedError) { + router.replace('/login') + return + } + setError(err?.message || '操作失败') + } + } + + const testProvider = async (provider: Provider) => { + setTestResult(null) + setError('') + + try { + const data = await adminFetchJson<{ + ok: boolean + latency_ms?: number + message?: string + }>(`/api/v1/admin/providers/${provider.id}/test`, { method: 'POST' }) + setTestResult(data) + } catch (err: any) { + if (err instanceof AdminUnauthorizedError) { + router.replace('/login') + return + } + setTestResult({ ok: false, message: err?.message || '测试失败' }) + } } return ( -
-
-

AI 配置管理

- -
+
+ + +
+ AI 配置管理 + 管理 AI Provider(模型、Base URL、API Key、默认/启用状态) +
+
+ + +
+
+ + {error && ( +
+ {error} +
+ )} - {/* Provider 列表 */} -
- - - - - - - - - - - - {providers.map((p) => ( - - - - - - - - ))} - -
名称模型 IDBase URL状态操作
- {p.name} - {p.is_default && ( - - 默认 - +
+
+ setQuery(e.target.value)} + placeholder="搜索:名称 / 模型 / Base URL" + /> +
+ +
+ +
+ + + + 名称 + 模型 + Base URL + 状态 + 操作 + + + + {isLoading ? ( + + + 加载中... + + + ) : filteredProviders.length === 0 ? ( + + + 暂无数据 + + + ) : ( + filteredProviders.map((p) => ( + + +
+
{p.name}
+ {p.is_default && 默认} +
+ {p.created_at && ( +
+ 创建于 {new Date(p.created_at).toLocaleString()} +
+ )} +
+ {p.model_id} + +
+ {p.base_url || '-'} +
+
+ + {p.is_active ? ( + 启用 + ) : ( + + 禁用 + + )} + + +
+ {!p.is_default && ( + + )} + + + + +
+
+
+ )) + )} +
+
+
+ + + + {dialogOpen && ( +
+ + + {editing ? '编辑' : '添加'} AI 配置 + + {editing + ? '更新配置项(API Key 留空则不修改)' + : '添加新的 Provider 配置'} + + + + {testResult && ( +
+ {testResult.ok ? ( +
+ 连接正常{typeof testResult.latency_ms === 'number' ? `(${testResult.latency_ms}ms)` : ''} +
+ ) : ( +
{testResult.message || '测试失败'}
)} -
{p.model_id}{p.base_url || '-'} - - {p.is_active ? '启用' : '禁用'} - - - -
-
+
+ )} - {/* 添加/编辑表单 */} - {showForm && ( -
-
-

- {editId ? '编辑' : '添加'} AI 配置 -

+
+
+ + setForm({ ...form, name: e.target.value })} + placeholder="OpenAI / Azure / 自建代理..." + /> +
+
+ + setForm({ ...form, model_id: e.target.value })} + placeholder="gpt-4o-mini" + /> +
+
-
-
- - setForm({ ...form, name: e.target.value })} - className="w-full p-2 border rounded" - /> -
-
- - setForm({ ...form, model_id: e.target.value })} - className="w-full p-2 border rounded" - placeholder="gpt-4o-mini" - /> -
-
- - + + setForm({ ...form, base_url: e.target.value })} - className="w-full p-2 border rounded" placeholder="https://api.openai.com/v1" /> +
+ 留空表示使用默认 OpenAI Base URL +
-
- - + +