1. 缩短键值的长度
在 Redis 中,每个键(key)都占用一定的内存空间。键名的长度直接决定了内存消耗,因此,短键名能够有效减少内存占用。此外,值(value)的存储也会占用内存。如果存储的数据是一个复杂的对象,采用更高效的序列化方式(例如 Protostuff 或 Kryo)也能帮助减少内存占用。
优化方法:
- 短键名:避免在键名中包含冗余信息。例如,可以将键名
user:profile:12345改为u:12345,这样就将键名的长度从 21 字节减少到 8 字节。 - 高效序列化:对于复杂对象,不要使用 Java 默认的
Serializable,而应该选择如 Protostuff 或 Kryo 等更高效的序列化工具。这些工具将对象压缩为更小的二进制格式,从而减少 Redis 存储的内存消耗。
优化示例:
// 使用 Protostuff 序列化
import io.protostuff.*;
public class RedisExample {
public static void main(String[] args) {
// 创建 ProtoBuffer Schema
Schema<UserProfile> schema = RuntimeSchema.getSchema(UserProfile.class);
// 创建一个对象
UserProfile user = new UserProfile("12345", "John", 30);
// 序列化为 Protostuff 二进制
byte[] bytes = ProtostuffIOUtil.toByteArray(user, schema, LinkedBuffer.allocate(512));
// 将数据存储到 Redis
jedis.set("user:12345".getBytes(), bytes);
}
}
通过使用短键名和高效的序列化方式,我们减少了存储的内存占用。
2. 共享对象池
Redis 内部维护了一个 整数对象池,用于存储 0 到 9999 之间的整数。当你存储整数类型的数据(如 SET key 123),Redis 会检查该整数是否在池中,如果是,它将直接使用池中的对象,而不是为每个新的整数分配新的内存。这有效减少了内存的消耗,避免了频繁创建相同整数的多个对象。
优化方法:
- 尽量使用整数:在存储整数值时,优先使用
int或long类型,而不是将它们转化为字符串存储。例如,SET key 123会比SET key "123"占用更少的内存。 - 使用共享池:通过整数对象池的机制,Redis 会避免为每个整数值创建单独的对象,从而节省内存。
优化示例:
import redis.clients.jedis.Jedis;
public class RedisExample {
public static void main(String[] args) {
Jedis jedis = new Jedis("localhost", 6379);
// 存储整数 123
jedis.set("key1", "123");
// 继续存储相同的整数值,Redis 会复用内存
jedis.set("key2", "123");
// 获取并输出 key1 和 key2 的值
System.out.println(jedis.get("key1")); // 输出 123
System.out.println(jedis.get("key2")); // 输出 123
}
}
在上面的代码中,两个 SET 操作都存储了相同的整数值 123。由于 Redis 会共享池中的整数对象,内存消耗会比将数字存储为字符串(例如 "123")要少得多。
简短 Demo 总结:
- 缩短键值的长度:通过简化键名和使用高效的序列化方式(如 Protostuff)来减少内存占用。
- 共享对象池:利用 Redis 内部的整数池避免重复分配内存,节省存储相同整数的开销。
这两种优化方式可以显著提升 Redis 存储效率,减少内存消耗,提升整体性能。
3. 字符串优化
在 Redis 中,字符串类型的数据占用的内存取决于其内容的类型和大小。当你存储数字时,Redis 会将其作为字符串进行存储,这可能会导致额外的内存开销。为了减少内存占用,应该尽量使用 int 或 long 类型存储数字,而不是将它们转化为字符串进行存储。
优化方法:
-
使用整数存储数字:Redis 会针对整数类型的数据优化存储,避免额外的内存开销。如果你存储的是数字,直接使用整数(如
SET key 123)而不是将其转换为字符串(如SET key "123"),这样可以节省空间。 -
启用 ziplist 结构优化小集合:Redis 会自动选择适当的数据结构来存储集合类型的数据。例如,对于小集合(如小的列表、哈希表或有序集合),Redis 会使用 ziplist 数据结构,它采用更紧凑的内存布局,从而减少内存的使用。
优化示例:
import redis.clients.jedis.Jedis;
public class RedisExample {
public static void main(String[] args) {
Jedis jedis = new Jedis("localhost", 6379);
// 存储整数值,避免作为字符串存储
jedis.set("score", "100"); // 字符串形式
jedis.set("score", "123"); // 使用整数更节省空间
// 存储一个小集合,Redis 会自动优化成 ziplist
jedis.lpush("


3118

被折叠的 条评论
为什么被折叠?



