Saturday, August 22, 2015

Redis Publish Subscribe Model



https://making.pusher.com/redis-pubsub-under-the-hood/
To track subscriptions, Redis uses a global variable pubsub_channels which maps channel names to sets of subscribed client objects. A client object represents a TCP-connected client by tracking that connection’s file descriptor.

When a client sends a SUBSCRIBE command, its client object gets added to the set of clients for that channel name. To PUBLISH, Redis looks up the subscribers in the pubsub_channels map, and for each client, it schedules a job to send the published message to the client’s socket.
Client connections can drop. Perhaps the client closed the connection, or a network cable was pulled. When this happens, Redis must clean up the client’s subscriptions. Let’s say Client A disconnects. To remove the client from the pubsub_channels structure, Redis would have to visit every channel (“donuts” and “bagels”) and remove the client from each channel’s subscription set.
But visiting every channel is inefficient: Redis should only need to visit the “donuts” channel, because that is the only one that Client A is subscribed to. To enable this, Redis annotates each client with its set of subscribed channels, and keeps this in sync with the main pubsub_channels structure. With this, instead of iterating over every channel, Redis only needs to visit the channels which it knows the client was subscribed to
I’ve described the data structures as “maps” and “sets”: the global pubsub_channelsvariable is logically a Map<ChannelName, Set<Client>>, and each client’s subscription set is a Set<ChannelName>

http://redis.io/topics/pubsub
SUBSCRIBEUNSUBSCRIBE and PUBLISH implement the Publish/Subscribe messaging paradigm where (citing Wikipedia) senders (publishers) are not programmed to send their messages to specific receivers (subscribers). Rather, published messages are characterized into channels, without knowledge of what (if any) subscribers there may be. 

Subscribers express interest in one or more channels, and only receive messages that are of interest, without knowledge of what (if any) publishers there are. This decoupling of publishers and subscribers can allow for greater scalability and a more dynamic network topology.
For instance in order to subscribe to channels foo and bar the client issues a SUBSCRIBE providing the names of the channels:
SUBSCRIBE foo bar
Messages sent by other clients to these channels will be pushed by Redis to all the subscribed clients.
A client subscribed to one or more channels should not issue commands, although it can subscribe and unsubscribe to and from other channels. 

The reply of the SUBSCRIBE and UNSUBSCRIBE operations are sent in the form of messages, so that the client can just read a coherent stream of messages where the first element indicates the type of message.

Pattern-matching subscriptions

The Redis Pub/Sub implementation supports pattern matching. Clients may subscribe to glob-style patterns in order to receive all the messages sent to channel names matching a given pattern.
For instance:
PSUBSCRIBE news.*
Will receive all the messages sent to the channel news.art.figurativenews.music.jazz, etc. All the glob-style patterns are valid, so multiple wildcards are supported.
PUNSUBSCRIBE news.*

https://davidmarquis.wordpress.com/2013/01/03/reliable-delivery-message-queues-with-redis/
Redis is a high performance key-value datastore that differs from other key-value solutions in the way it handles values. Instead of just storing values as simple strings, it recognizes multiple specific data types such as Lists, Sets, Hashes (maps), Strings or Numbers. Each data type has its own set of features to manipulate the data it contains in an atomic manner, making it an ideal tool for highly distributed system where concurrency is a potential issue.

  • although Redis requires everything you store in it to fit in memory, it supports persistence to disk.
  • Redis allowed for all of the implementation characteristics we were looking for, namely:
    • Concurrency: Because all operations in Redis are atomic, supporting concurrency without too much of a hassle is straightforward.
    • Persistence: Configured properly, we can ensure persistence of our queues to disk using one of the supported Redis persistence strategies.

Why not use Redis Pub/Sub?
  1. What Redis offers with Pub/Sub is a listener model, where each subscriber receives each messages when it is listening, but won’t receive them when not connected. 
  2. In a clustered environment where you have multiple instances of your consumer component running at the same time, each instance would receive each message produced on the channel. We wanted to make sure any given message got consumed once per logical consumer, even when multiple instances of this component are running. 
Hence the name of this post “Reliable Delivery”, because we wanted to make sure every logical consumer eventually receives all messages produced on a queue once and only once, even when not connected – due to, for example, a deployment, a restart or a component failure/crash.
Redis Pub/Sub with Spring
http://aredko.blogspot.com/2012/09/redis-pubsub-using-spring.html
36    @Bean
37    MessageListenerAdapter messageListener() {
38        return new MessageListenerAdapter( new RedisMessageListener() );
39    }
40
41    @Bean
42    RedisMessageListenerContainer redisContainer() {
43        final RedisMessageListenerContainer container = new RedisMessageListenerContainer();
44
45        container.setConnectionFactory( jedisConnectionFactory() );
46        container.addMessageListener( messageListener(), topic() );
47
48        return container;
49    }
50  
51    @Bean
52    IRedisPublisher redisPublisher() {
53        return new RedisPublisherImpl( redisTemplate(), topic() );
54    }
55
56    @Bean
57    ChannelTopic topic() {
58        return new ChannelTopic( "pubsub:queue" );
59    }

11public class RedisPublisherImpl implements IRedisPublisher {
12    private final RedisTemplate< String, Object > template;
13    private final ChannelTopic topic;
14    private final AtomicLong counter = new AtomicLong( 0 );
15
16    public RedisPublisherImpl( final RedisTemplate< String, Object > template,
17            final ChannelTopic topic ) {
18        this.template = template;
19        this.topic = topic;
20    }
21
22    @Scheduled( fixedDelay = 100 )
23    public void publish() {
24        template.convertAndSend( topic.getTopic(), "Message " + counter.incrementAndGet() +
25            ", " + Thread.currentThread().getName() );
26 }
27}

06public class RedisMessageListener implements MessageListener {
07    @Override
08    public void onMessage( final Message message, final byte[] pattern ) {
09        System.out.println( "Message received: " + message.toString() );
10    }
11}
http://city81.blogspot.com/2014/03/redis-publish-subscribe-and-long.html
Ruby Example: http://tutorials.jumpstartlab.com/topics/asynchronous_messaging_with_pubsub.html

Labels

Review (572) System Design (334) System Design - Review (198) Java (189) Coding (75) Interview-System Design (65) Interview (63) Book Notes (59) Coding - Review (59) to-do (45) Linux (43) Knowledge (39) Interview-Java (35) Knowledge - Review (32) Database (31) Design Patterns (31) Big Data (29) Product Architecture (28) MultiThread (27) Soft Skills (27) Concurrency (26) Cracking Code Interview (26) Miscs (25) Distributed (24) OOD Design (24) Google (23) Career (22) Interview - Review (21) Java - Code (21) Operating System (21) Interview Q&A (20) System Design - Practice (20) Tips (19) Algorithm (17) Company - Facebook (17) Security (17) How to Ace Interview (16) Brain Teaser (14) Linux - Shell (14) Redis (14) Testing (14) Tools (14) Code Quality (13) Search (13) Spark (13) Spring (13) Company - LinkedIn (12) How to (12) Interview-Database (12) Interview-Operating System (12) Solr (12) Architecture Principles (11) Resource (10) Amazon (9) Cache (9) Git (9) Interview - MultiThread (9) Scalability (9) Trouble Shooting (9) Web Dev (9) Architecture Model (8) Better Programmer (8) Cassandra (8) Company - Uber (8) Java67 (8) Math (8) OO Design principles (8) SOLID (8) Design (7) Interview Corner (7) JVM (7) Java Basics (7) Kafka (7) Mac (7) Machine Learning (7) NoSQL (7) C++ (6) Chrome (6) File System (6) Highscalability (6) How to Better (6) Network (6) Restful (6) CareerCup (5) Code Review (5) Hash (5) How to Interview (5) JDK Source Code (5) JavaScript (5) Leetcode (5) Must Known (5) Python (5)

Popular Posts