Best Practices for Using Alibaba Cloud Redis: Key Design, Commands, Client Usage, and Tools
This article outlines Alibaba Cloud Redis development guidelines, covering key naming conventions, value design, command usage, client configuration, lifecycle management, and related tools, with practical examples and code snippets to help avoid common pitfalls and improve performance.
1. Key Design
1.1 Key Name Design
Recommendation: readability and manageability – use a business or database name as a prefix to avoid key collisions, separated by colons, e.g., ugc:video:1 .
Recommendation: keep keys concise while preserving semantics; long keys increase memory usage, e.g., user:{uid}:friends:messages:{mid} can be shortened to u:{uid}:fr:m:{mid} .
Mandatory: do not include special characters such as spaces, line breaks, quotes, or escape characters.
1.2 Value Design
Mandatory: avoid big keys to prevent network traffic spikes and slow queries. Keep strings under 10KB and limit hash, list, set, zset elements to no more than 5,000.
Recommendation: choose appropriate data types and optimize memory encoding (e.g., ziplist) while balancing memory savings and performance.
Example of a poor approach using separate SET commands:
set user:1:name tom
set user:1:age 19
set user:1:favor footballBetter approach using a hash:
hmset user:1 name tom age 19 favor football1.3 Key Lifecycle Management
Set expiration times with EXPIRE (preferably staggered to avoid mass expirations). For non‑expiring data, monitor IDLETIME .
2. Command Usage
2.1 Prefer O(N) Commands with Known N
Commands like HGETALL , LRANGE , SMEMBERS , ZRANGE , SINTER are acceptable if the size (N) is known; otherwise use HSCAN , SSCAN , ZSCAN for incremental iteration.
2.2 Disable Dangerous Commands
Prohibit KEYS , FLUSHALL , FLUSHDB in production, using Redis rename mechanism or scanning alternatives.
2.3 Use of SELECT
Redis multiple databases are weakly supported; avoid relying on them for isolation as many clients handle them poorly.
2.4 Batch Operations for Efficiency
Native batch commands like MGET , MSET are atomic; for higher throughput use pipelines (non‑atomic) but limit batch size (e.g., ≤500 elements) based on element size.
1. Native commands are atomic, pipeline is not.
2. Pipeline can bundle different commands, native cannot.
3. Both client and server must support pipeline.2.5 Transaction Usage
Redis transactions are limited (no rollback) and, in cluster mode, all keys in a transaction must reside in the same slot (use hashtags to co‑locate keys).
2.6 Lua Scripts in Cluster Mode
All keys must be passed via the KEYS array; otherwise Redis returns -ERR bad lua script for redis cluster . Additionally, all keys must belong to a single slot.
2.7 Monitor Command
Use MONITOR sparingly and avoid long‑running sessions.
3. Client Usage
3.1 Instance Isolation
Avoid sharing a single Redis instance across unrelated applications; separate business domains and expose shared data via services.
3.2 Connection Pooling
Use a client with a connection pool to control connections and improve efficiency. Example (Jedis):
Jedis jedis = null;
try {
jedis = jedisPool.getResource();
// execute commands
jedis.executeCommand();
} catch (Exception e) {
logger.error("op key {} error: " + e.getMessage(), key, e);
} finally {
if (jedis != null) jedis.close(); // returns to pool
}3.3 Circuit Breaker
In high‑concurrency scenarios, add a circuit‑breaker (e.g., Netflix Hystrix) to the client.
3.4 Security
Set strong passwords and enable SSL encryption when needed (supported by Alibaba Cloud Redis).
3.5 Memory Eviction Policy
Choose an appropriate maxmemory-policy (default volatile‑lru ). Other policies include allkeys‑lru , allkeys‑random , volatile‑random , volatile‑ttl , and noeviction .
4. Related Tools
4.1 Data Synchronization
Use tools like redis‑port for cross‑instance data sync.
4.2 Big‑Key Search
Utilize built‑in utilities to locate large keys.
4.3 Hot‑Key Detection
Monitor hot keys (short‑term MONITOR usage recommended). Alibaba Cloud Redis already mitigates hot‑key issues at the kernel level.
5. Appendix: Deleting Big Keys
Pipeline can accelerate deletion. Redis 4.0 supports asynchronous key deletion.
5.1 Delete Large Hashes (hscan + hdel)
public void delBigHash(String host, int port, String password, String bigHashKey) {
Jedis jedis = new Jedis(host, port);
if (password != null && !"".equals(password)) {
jedis.auth(password);
}
ScanParams scanParams = new ScanParams().count(100);
String cursor = "0";
do {
ScanResult
> scanResult = jedis.hscan(bigHashKey, cursor, scanParams);
List
> entryList = scanResult.getResult();
if (entryList != null && !entryList.isEmpty()) {
for (Entry
entry : entryList) {
jedis.hdel(bigHashKey, entry.getKey());
}
}
cursor = scanResult.getStringCursor();
} while (!"0".equals(cursor));
jedis.del(bigHashKey);
}5.2 Delete Large Lists (ltrim)
public void delBigList(String host, int port, String password, String bigListKey) {
Jedis jedis = new Jedis(host, port);
if (password != null && !"".equals(password)) {
jedis.auth(password);
}
long llen = jedis.llen(bigListKey);
int counter = 0;
int left = 100;
while (counter < llen) {
jedis.ltrim(bigListKey, left, llen);
counter += left;
}
jedis.del(bigListKey);
}5.3 Delete Large Sets (sscan + srem)
public void delBigSet(String host, int port, String password, String bigSetKey) {
Jedis jedis = new Jedis(host, port);
if (password != null && !"".equals(password)) {
jedis.auth(password);
}
ScanParams scanParams = new ScanParams().count(100);
String cursor = "0";
do {
ScanResult
scanResult = jedis.sscan(bigSetKey, cursor, scanParams);
List
memberList = scanResult.getResult();
if (memberList != null && !memberList.isEmpty()) {
for (String member : memberList) {
jedis.srem(bigSetKey, member);
}
}
cursor = scanResult.getStringCursor();
} while (!"0".equals(cursor));
jedis.del(bigSetKey);
}5.4 Delete Large Sorted Sets (zscan + zrem)
public void delBigZset(String host, int port, String password, String bigZsetKey) {
Jedis jedis = new Jedis(host, port);
if (password != null && !"".equals(password)) {
jedis.auth(password);
}
ScanParams scanParams = new ScanParams().count(100);
String cursor = "0";
do {
ScanResult
scanResult = jedis.zscan(bigZsetKey, cursor, scanParams);
List
tupleList = scanResult.getResult();
if (tupleList != null && !tupleList.isEmpty()) {
for (Tuple tuple : tupleList) {
jedis.zrem(bigZsetKey, tuple.getElement());
}
}
cursor = scanResult.getStringCursor();
} while (!"0".equals(cursor));
jedis.del(bigZsetKey);
}Source: developer.aliyun.com/article/531067 (Author: Fu Lei‑Qi Yang)
Java Captain
Focused on Java technologies: SSM, the Spring ecosystem, microservices, MySQL, MyCat, clustering, distributed systems, middleware, Linux, networking, multithreading; occasionally covers DevOps tools like Jenkins, Nexus, Docker, ELK; shares practical tech insights and is dedicated to full‑stack Java development.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.