Redis 作为缓存,可以极大地提高应用程序的响应速度,适用于存储会话数据、热点数据、频繁访问的数据等。
Node.js 实现用户会话存储
const redis = require("redis");
const client = redis.createClient();
client.on("error", (err) => {
console.error("Redis client not connected to the server:", err);
});
client.on("connect", () => {
console.log("Redis client connected to the server");
});
const sessionId = "session:123456";
const sessionData = { userId: 1, username: "john_doe" };
// 设置会话数据,并设置过期时间为 3600 秒
client.hmset(sessionId, sessionData, (err, res) => {
if (err) console.error(err);
else console.log("Session data set:", res);
client.expire(sessionId, 3600);
});
// 获取会话数据
client.hgetall(sessionId, (err, obj) => {
if (err) console.error(err);
else console.log("Session data retrieved:", obj);
client.quit();
});
Java 实现用户会话存储
import redis.clients.jedis.Jedis;
import java.util.HashMap;
import java.util.Map;
public class RedisSessionExample {
public static void main(String[] args) {
Jedis jedis = new Jedis("localhost");
String sessionId = "session:123456";
Map<String, String> sessionData = new HashMap<>();
sessionData.put("userId", "1");
sessionData.put("username", "john_doe");
// 设置会话数据,并设置过期时间为 3600 秒
jedis.hmset(sessionId, sessionData);
jedis.expire(sessionId, 3600);
// 获取会话数据
Map<String, String> retrievedData = jedis.hgetAll(sessionId);
System.out.println("Session data retrieved: " + retrievedData);
jedis.close();
}
}
利用 Redis 的有序集合来实现排行榜,例如游戏积分榜、社交应用的粉丝排名。
Node.js 实现游戏积分排行榜
const redis = require("redis");
const client = redis.createClient();
client.on("error", (err) => {
console.error("Redis client not connected to the server:", err);
});
client.on("connect", () => {
console.log("Redis client connected to the server");
});
const leaderboardKey = "game:leaderboard";
// 添加用户分数
client.zadd(leaderboardKey, 100, "alice");
client.zadd(leaderboardKey, 200, "bob");
client.zadd(leaderboardKey, 150, "charlie");
// 获取排行榜前两名
client.zrevrange(leaderboardKey, 0, 1, "WITHSCORES", (err, members) => {
if (err) console.error(err);
else console.log("Top players:", members);
client.quit();
});
Java 实现游戏积分排行榜
import redis.clients.jedis.Jedis;
import java.util.Set;
public class RedisLeaderboardExample {
public static void main(String[] args) {
Jedis jedis = new Jedis("localhost");
String leaderboardKey = "game:leaderboard";
// 添加用户分数
jedis.zadd(leaderboardKey, 100, "alice");
jedis.zadd(leaderboardKey, 200, "bob");
jedis.zadd(leaderboardKey, 150, "charlie");
// 获取排行榜前两名
Set<String> topPlayers = jedis.zrevrange(leaderboardKey, 0, 1);
System.out.println("Top players: " + topPlayers);
jedis.close();
}
}
在分布式系统中,Redis 可用于实现分布式锁,确保共享资源的互斥访问。
Node.js 实现简单的分布式锁
const redis = require("redis");
const client = redis.createClient();
const lockKey = "lock:resource";
const lockTimeout = 10;
client.on("error", (err) => {
console.error("Redis client not connected to the server:", err);
});
client.on("connect", () => {
console.log("Redis client connected to the server");
});
function acquireLock(callback) {
client.set(lockKey, "locked", "NX", "EX", lockTimeout, (err, res) => {
callback(err, res === "OK");
});
}
function releaseLock() {
client.del(lockKey);
}
// 获取锁
acquireLock((err, acquired) => {
if (err) {
console.error(err);
} else if (acquired) {
console.log("Lock acquired, performing operation...");
setTimeout(() => {
releaseLock();
console.log("Lock released.");
client.quit();
}, 5000);
} else {
console.log("Unable to acquire lock.");
client.quit();
}
});
Java 实现简单的分布式锁
import redis.clients.jedis.Jedis;
public class RedisLockExample {
private static final String LOCK_KEY = "lock:resource";
private static final int LOCK_TIMEOUT = 10;
public static void main(String[] args) {
try (Jedis jedis = new Jedis("localhost")) {
if (acquireLock(jedis)) {
System.out.println("Lock acquired, performing operation...");
try {
Thread.sleep(5000); // 模拟操作时间
} catch (InterruptedException e) {
e.printStackTrace();
}
releaseLock(jedis);
System.out.println("Lock released.");
} else {
System.out.println("Unable to acquire lock.");
}
}
}
public static boolean acquireLock(Jedis jedis) {
String result = jedis.set(LOCK_KEY, "locked", "NX", "EX", LOCK_TIMEOUT);
return "OK".equals(result);
}
public static void releaseLock(Jedis jedis) {
jedis.del(LOCK_KEY);
}
}
Redis 的列表和发布/订阅机制适用于构建简单的消息队列系统。
Node.js 实现生产者-消费者模式
const redis = require("redis");
const client = redis.createClient();
const queueKey = "task:queue";
client.on("error", (err) => {
console.error("Redis client not connected to the server:", err);
});
client.on("connect", () => {
console.log("Redis client connected to the server");
});
// 生产者
function producer() {
for (let i = 0; i < 5; i++) {
const task = `task_${i}`;
client.lpush(queueKey, task, (err) => {
if (err) console.error(err);
else console.log(`Produced ${task}`);
});
}
}
// 消费者
function consumer() {
client.brpop(queueKey, 5, (err, task) => {
if (err) {
console.error(err);
} else if (task) {
console.log(`Consumed ${task[1]}`);
consumer();
} else {
console.log("No task, consumer is waiting...");
setTimeout(consumer, 1000);
}
});
}
// 启动生产者和消费者
producer();
consumer();
Java 实现生产者-消费者模式
import redis.clients.jedis.Jedis;
import redis.clients.jedis.ListPosition;
import redis.clients.jedis.resps.Tuple;
public class RedisQueueExample {
private static final String QUEUE_KEY = "task:queue";
public static void main(String[] args) {
new Thread(RedisQueueExample::producer).start();
new Thread(RedisQueueExample::consumer).start();
}
// 生产者
public static void producer() {
try (Jedis jedis = new Jedis("localhost")) {
for (int i = 0; i < 5; i++) {
String task = "task_" + i;
jedis.lpush(QUEUE_KEY, task);
System.out.println("Produced " + task);
Thread.sleep(1000); // 模拟生产间隔
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
// 消费者
public static void consumer() {
try (Jedis jedis = new Jedis("localhost")) {
while (true) {
String task = jedis.brpop(5, QUEUE_KEY).get(1);
if (task != null) {
System.out.println("Consumed " + task);
} else {
System.out.println("No task, consumer is waiting...");
Thread.sleep(1000);
}
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
使用 Redis 的计数器和 HyperLogLog,可以实现实时统计功能,如网站访问量、在线
用户数等。
Node.js 实现网站访问量统计
const redis = require("redis");
const client = redis.createClient();
const pageViewsKey = "page:views";
client.on("error", (err) => {
console.error("Redis client not connected to the server:", err);
});
client.on("connect", () => {
console.log("Redis client connected to the server");
});
function incrementPageViews() {
client.incr(pageViewsKey, (err, newValue) => {
if (err) console.error(err);
else console.log("Page views:", newValue);
});
}
// 模拟页面访问
setInterval(incrementPageViews, 2000);
Java 实现网站访问量统计
import redis.clients.jedis.Jedis;
public class RedisPageViewsExample {
private static final String PAGE_VIEWS_KEY = "page:views";
public static void main(String[] args) {
try (Jedis jedis = new Jedis("localhost")) {
while (true) {
incrementPageViews(jedis);
Thread.sleep(2000); // 模拟页面访问间隔
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public static void incrementPageViews(Jedis jedis) {
long pageViews = jedis.incr(PAGE_VIEWS_KEY);
System.out.println("Page views: " + pageViews);
}
}
主从复制是一种简单的高可用方案,通过配置多个从节点来分担读负载,并在主节点故障时进行故障切换。
Node.js 配置主从复制
const redis = require("redis");
const master = redis.createClient({ port: 6379 });
master.set("key", "value", (err, res) => {
if (err) console.error(err);
else console.log("Set in master:", res);
});
master.quit();
const redis = require("redis");
const slave = redis.createClient({ port: 6380 });
slave.get("key", (err, value) => {
if (err) console.error(err);
else console.log("Retrieved from slave:", value);
slave.quit();
});
Java 配置主从复制
import redis.clients.jedis.Jedis;
public class RedisMasterExample {
public static void main(String[] args) {
try (Jedis master = new Jedis("localhost", 6379)) {
master.set("key", "value");
System.out.println("Set in master");
}
}
}
import redis.clients.jedis.Jedis;
public class RedisSlaveExample {
public static void main(String[] args) {
try (Jedis slave = new Jedis("localhost", 6380)) {
String value = slave.get("key");
System.out.println("Retrieved from slave: " + value);
}
}
}
哨兵模式用于自动故障转移和系统监控。
Node.js 配置 Redis 哨兵
redis-server --port 6379
redis-server --port 6380 --slaveof 127.0.0.1 6379
redis-server --port 6381 --slaveof 127.0.0.1 6379
redis-sentinel sentinel.conf
const Redis = require("ioredis");
const sentinel = new Redis({
sentinels: [{ host: "localhost", port: 26379 }],
name: "mymaster"
});
sentinel.get("key", (err, value) => {
if (err) console.error(err);
else console.log("Value from sentinel:", value);
sentinel.quit();
});
Java 配置 Redis 哨兵
import redis.clients.jedis.JedisSentinelPool;
import redis.clients.jedis.Jedis;
import java.util.HashSet;
import java.util.Set;
public class RedisSentinelExample {
public static void main(String[] args) {
Set<String> sentinels = new HashSet<>();
sentinels.add("localhost:26379");
try (JedisSentinelPool sentinelPool = new JedisSentinelPool("mymaster", sentinels);
Jedis jedis = sentinelPool.getResource()) {
String value = jedis.get("key");
System.out.println("Value from sentinel: " + value);
}
}
}
Node.js 配置 Redis 集群
const Redis = require("ioredis");
const cluster = new Redis.Cluster([
{ host: "127.0.0.1", port: 7000 },
{ host: "127.0.0.1", port: 7001 },
{ host: "127.0.0.1", port: 7002 }
]);
cluster.set("key", "value", (err, res) => {
if (err) console.error(err);
else console.log("Set in cluster:", res);
cluster.get("key", (err, value) => {
if (err) console.error(err);
else console.log("Retrieved from cluster:", value);
cluster.quit();
});
});
Java 配置 Redis 集群
import redis.clients.jedis.JedisCluster;
import java.util.HashSet;
import java.util.Set;
import redis.clients.jedis.HostAndPort;
public class RedisClusterExample {
public static void main(String[] args) {
Set<HostAndPort> jedisClusterNodes = new HashSet<>();
jedisClusterNodes.add(new HostAndPort("127.0.0.1", 7000));
jedisClusterNodes.add(new HostAndPort("127.0.0.1", 7001));
jedisClusterNodes.add(new HostAndPort("127.0.0.1", 7002));
try (JedisCluster jedisCluster = new JedisCluster(jedisClusterNodes)) {
jedisCluster.set("key", "value");
String value = jedisCluster.get("key");
System.out.println("Retrieved from cluster: " + value);
}
}
}
除了自建 Redis 集群之外,还有许多云服务提供商提供托管的 Redis 服务,如 AWS ElastiCache for Redis、Azure Redis Cache、Google Cloud Memorystore 等。这些服务通常提供更简单的管理和监控工具,可以方便地实现高可用和自动扩展。
Redis 以其高性能、多数据结构支持和丰富的功能,成为许多应用程序中不可或缺的缓存和存储方案。通过主从复制、哨兵模式和 Redis 集群等机制,Redis 提供了可靠的高可用性和扩展性,适用于各种规模和复杂性的应用场景。了解并合理应用 Redis 的这些特性,可以显著提高系统的性能和稳定性。
如果有其他具体问题或示例需要解释,请随时告诉我!