将 Redis 用作协调服务
设计利用 Redis 实现服务发现、配置管理和服务间通信的解决方案
将 Redis 用作协调服务 是 CoddyKit 上的免费 Redis Caching & Messaging (Pub/Sub, Streams) 课时。 这是第 3 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 Redis Caching & Messaging (Pub/Sub, Streams) 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 Redis Caching & Messaging (Pub/Sub, Streams) 课程共包含 4 节课。
本课时的部分内容尚未翻译,以英文显示。
Coordination in Distributed Systems
In distributed systems, multiple services work together to achieve a common goal. For these services to function smoothly, they often need to find each other, share configuration, and communicate in an organized way.
This 'orchestration' is called service coordination. Without it, services might struggle to locate their dependencies, use outdated settings, or fail to process tasks efficiently.
Redis's Role in Coordination
Redis, with its speed, atomic operations, and versatile data structures, is an excellent choice for a coordination service.
- Atomic Operations: Ensures operations are completed entirely or not at all, crucial for consistency.
- Data Structures: Hashes, Lists, and Sets provide flexible ways to store and manage coordination data.
- Pub/Sub: Enables real-time notification for events like configuration changes.
These features allow Redis to act as a central hub for various coordination patterns.
Understanding Service Discovery
Service discovery is how applications and microservices locate and communicate with each other on a network. In dynamic environments (like cloud deployments), service instances constantly scale up and down, and their network locations (IPs, ports) can change.
A service discovery mechanism allows services to register their presence and clients to look them up by name, rather than hardcoding addresses.
Registering Services with Redis
We can use a Redis Hash to store information about active service instances. The hash key could be 'services:<serviceName>', and fields would be '<instanceId>' mapping to '<IP:Port>'.
Try running this example to register a service instance:
import redis.clients.jedis.Jedis;
public class ServiceRegistry {
public static void main(String[] args) {
Jedis jedis = new Jedis("localhost"); // Connect to Redis
String serviceName = "paymentService";
String instanceId = "paymentsvc-001";
String instanceAddress = "192.168.1.10:8080";
// Register service instance
jedis.hset("services:" + serviceName, instanceId, instanceAddress);
System.out.println("Registered " + serviceName + " instance: " + instanceAddress);
jedis.close();
}
}Discovering Active Services
Once services are registered, clients or other services can query Redis to find available instances. The HGETALL command retrieves all fields and values from a hash, giving us a list of all active instances for a given service.
Run this code to discover the registered service:
import redis.clients.jedis.Jedis;
import java.util.Map;
public class ServiceDiscovery {
public static void main(String[] args) {
Jedis jedis = new Jedis("localhost");
String serviceName = "paymentService";
// Discover all instances for a service
Map<String, String> instances = jedis.hgetAll("services:" + serviceName);
if (instances.isEmpty()) {
System.out.println("No instances found for " + serviceName);
} else {
System.out.println("Active " + serviceName + " instances:");
for (Map.Entry<String, String> entry : instances.entrySet()) {
System.out.println(" ID: " + entry.getKey() + ", Address: " + entry.getValue());
}
}
jedis.close();
}
}Centralized Configuration Management
Another crucial coordination task is managing application configurations. Instead of hardcoding settings or using local files, centralized configuration management stores configurations in a single, accessible location.
This allows for dynamic updates, consistent settings across all service instances, and avoids redeployments for simple configuration changes.
Storing Configs in Redis
Redis Hashes are well-suited for storing structured application configurations. Each hash can represent the configuration for a specific application or module, with fields being individual settings.
Here's an example of setting and retrieving configuration for an application:
import redis.clients.jedis.Jedis;
import java.util.Map;
public class ConfigManager {
public static void main(String[] args) {
Jedis jedis = new Jedis("localhost");
String appConfigKey = "app:myApp:config";
// Set configuration properties
jedis.hset(appConfigKey, "dbHost", "my-db.example.com");
jedis.hset(appConfigKey, "dbPort", "5432");
jedis.hset(appConfigKey, "logLevel", "INFO");
System.out.println("Configuration updated for myApp.");
// Retrieve all configuration
Map<String, String> config = jedis.hgetAll(appConfigKey);
System.out.println("Current myApp configuration:");
for (Map.Entry<String, String> entry : config.entrySet()) {
System.out.println(" " + entry.getKey() + ": " + entry.getValue());
}
jedis.close();
}
}Distributing Config Updates
For dynamic configuration, services need a way to be notified when settings change. While polling Redis periodically is an option, using Redis's Pub/Sub mechanism is more efficient.
When a configuration is updated, the configuration service can publish a message to a specific channel (e.g., 'config:updates'). All subscribed services would then receive this notification and could fetch the latest configuration.
Task Queues for Inter-Service Work
Redis Lists can serve as simple yet powerful task queues, allowing services to coordinate by distributing work. One service pushes tasks onto a list (LPUSH or RPUSH), and another service pulls tasks from it (RPOP or LPOP).
Using blocking pop operations like BRPOP or BLPOP, workers can wait for tasks without busy-looping, making it highly efficient.
import redis.clients.jedis.Jedis;
import java.util.List;
public class TaskConsumer {
public static void main(String[] args) {
Jedis jedis = new Jedis("localhost");
String taskQueueKey = "tasks:processing";
System.out.println("Worker started, waiting for tasks...");
// Simulate pushing a task for the demo to ensure something is there
jedis.lpush(taskQueueKey, "process_order_123");
// Blockingly pop a task from the right of the list
// 0 means wait indefinitely until a task is available
List<String> result = jedis.brpop(0, taskQueueKey);
if (result != null && result.size() > 1) {
String queueName = result.get(0); // The key from which the element was popped
String task = result.get(1); // The popped element
System.out.println("Received task '" + task + "' from queue '" + queueName + "'");
// Simulate processing
try { Thread.sleep(1000); } catch (InterruptedException e) {}
System.out.println("Task '" + task + "' processed.");
}
jedis.close();
}
}Quick Check: Coordination Patterns
Which of the following Redis features or commands are suitable for implementing service coordination patterns in a distributed system?
Lesson Summary
In this lesson, we explored how Redis can act as a powerful coordination service for distributed systems. We covered:
- Using Redis Hashes for dynamic service discovery, allowing services to register and be found.
- Leveraging Redis Hashes and Strings for centralized configuration management.
- Employing Redis Pub/Sub to facilitate dynamic configuration updates.
- Building task queues with Redis Lists (
LPUSH/BRPOP) for inter-service work distribution.
By using Redis for these patterns, you can build more resilient, scalable, and manageable distributed applications.
常见问题解答
「将 Redis 用作协调服务」课时是免费的吗?
是的 — 「将 Redis 用作协调服务」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 Redis Caching & Messaging (Pub/Sub, Streams) 课程的其余内容,请升级到 CoddyKit PRO。 Redis Caching & Messaging (Pub/Sub, Streams) 课程共包含 4 节课。
「将 Redis 用作协调服务」这节课中我会学到什么?
设计利用 Redis 实现服务发现、配置管理和服务间通信的解决方案 你通过在浏览器中直接运行的动手代码来练习 Redis Caching & Messaging (Pub/Sub, Streams),全天候 AI 导师会在你学习这节课的过程中回答你的问题。
学习 Redis Caching & Messaging (Pub/Sub, Streams) 需要有经验吗?
无需任何先前经验。CoddyKit 上的 Redis Caching & Messaging (Pub/Sub, Streams) 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 3 节课,共 4 节。
「将 Redis 用作协调服务」课时需要多长时间?
大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。
我能在这节 Redis Caching & Messaging (Pub/Sub, Streams) 课中编写并运行代码吗?
能。每节 Redis Caching & Messaging (Pub/Sub, Streams) 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。
此课程中的所有课时
- 使用 Redis 实现分布式锁
- 领导者选举模式
- 将 Redis 用作协调服务
- 分布式限流