redis stream基本使用
redis操作
list
基本使用
从左边入队
lpus
从左边出队
lpop
从右边入队
rpush
从右边出队
rpop
查询长度
llen key
pub/sub
PUBLISH channel message //将信息 message 发送到指定的频道 channel
PUBLISH channel_1 messagesada
SUBSCRIBE channel [channel ...] //订阅给定的一个或多个频道的信息。 订阅了之后,会一直保持连接,当有消息进来会直接打印
SUBSCRIBE channel_1
stream
Consumer Group :消费组,使用 XGROUP CREATE 命令创建,一个消费组有多个消费者(Consumer)。(同一个消息会被所有组都接收)
last_delivered_id :游标,每个消费组会有个游标 last_delivered_id,任意一个消费者读取了消息都会使游标 last_delivered_id 往前移动。(每个组内,每条消息只能被消费一次)
pending_ids :消费者(Consumer)的状态变量,作用是维护消费者的未确认的 id。 pending_ids 记录了当前已经被客户端读取的消息,但是还没有 ack (这个可以对未被确认的消息进行二次消费)
增加消息
xadd key ID filed value[value...]
查询长度
xlen key
查询消息内容
xrange key start end [count count]
xreverange key end start [count count]
xread [count count] [block milliseconds] streams key[key...] id[id..] (起始ID,0是最小 开区间,不包含该ID)
xread count 10 streams key_2 0
创建组
xgroup create key gruopname id-or-$ [MKSTREAM]
xgroup create mygroup name 0 MKSTREAM //表示从头消费
xgroup create mygroup name2 $ //表示从尾部消费
MKSTREAM:如果流不存在就需要这个参数-表示创建一个空流
XGROUP create test_stream group1 0
消费组
XREADGROUP GROUP group consumer [COUNT count] [BLOCK milliseconds] [NOACK] STREAMS key [key ...] ID [ID ...]
xreadgroup group 组名称 消费者名称 streams key id
XREADGROUP GROUP mygroup Alice STREAMS mystream >
XREADGROUP GROUP mygroup Alice STREAMS mystream 0
确认组内某个ID
XACK key 组名称 id
XACK mystream mygroup 1645373584093-0
查看流信息
xinfo stream key
XINFO stream mystream
基本使用
添加(消息)流
xadd key ID field value [field value ...]
例如:
xadd myKey * name myk llk ssu
(其中 * 表示redis自增)
删除(消息)流
xdel key ID
获取(消息)流的长度
xlen key
xlen myKey
获取消息列表,会自动过滤已经删除的消息
xrange key start end [COUNT count]
XRANGE myKe - +
(
-表示最小值
+表示最大值
count:可选 表示限制的查找长度
)
获取消息列表,会自动过滤已经删除的消息
XREVRANGE key end start [COUNT count]
(
-表示最小值
+表示最大值
count:可选 表示限制的查找长度
)
xrange 和xrevrange 的区别是xrange是顺序 而xreverange是逆序
以阻塞或非阻塞方式获取消息列表
XREAD count 2 [BLOCK milliseconds] STREAMS myKey[key... ] ID(开始ID,但不包含这个ID,开区间)
BLOCK milliseconds:阻塞毫秒数
[key..] 需要查找的key数组
java Jedis
maven依赖
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>3.3.0</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.78</version>
</dependency>
list
生产者
import java.util.List;
import com.alibaba.fastjson.JSON;
import redis.clients.jedis.Jedis;
/***
*
* list 生产者
*/
public class ListProducter {
public static void main(String[] args) {
Thread thread =new Thread(()->{
Jedis jedis = new Jedis("192.168.81.132");
jedis.auth("password");
long start = System.currentTimeMillis();
while(true) {
List<String> blpop = jedis.blpop(120, "list");
System.out.println("打印输出:"+JSON.toJSONString(blpop));
if( (System.currentTimeMillis() - start) > 3600 * 1000) {
break;
}
}
jedis.close();
});
thread.start();
}
}
消费者
import java.util.Random;
import redis.clients.jedis.Jedis;
/**
* list 消费者
*
*/
public class ListCustomer {
public static void main(String[] args) {
Thread thread =new Thread(()->{
Jedis jedis = new Jedis("192.168.81.132");
jedis.auth("password");
long start = System.currentTimeMillis();
Random random = new Random();
while(true) {
jedis.lpush("list", String.valueOf(random.nextInt(1000)));
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
if( (System.currentTimeMillis() - start) > 3600 * 1000) {
break;
}
}
jedis.close();
});
thread.start();
}
}
pub/sub
生产者
import java.util.Random;
import redis.clients.jedis.Jedis;
/**
* pub 生产消息
*
*/
public class PubProducter {
public static void main(String[] args) {
Thread thread =new Thread(()->{
Jedis jedis = new Jedis("192.168.81.132");
jedis.auth("password");
long start = System.currentTimeMillis();
Random random = new Random();
while(true) {
jedis.publish("message_pub", String.valueOf(random.nextInt(1000)));
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
if( (System.currentTimeMillis() - start) > 3600 * 1000) {
break;
}
}
jedis.close();
});
thread.start();
}
}
消费者
监听
import redis.clients.jedis.JedisPubSub;
public class Subscriber extends JedisPubSub{
@Override
public void onMessage(String channel, String message) {
System.out.println("渠道:"+channel+"\t消息为:"+message);
}
@Override
public void onSubscribe(String channel, int subscribedChannels) {
System.out.println("成功订阅:"+channel+"\nsubscribedChannels:"+subscribedChannels);
}
@Override
public void onUnsubscribe(String channel, int subscribedChannels) {
System.out.println("取消订阅:"+channel+"\nsubscribedChannels:"+subscribedChannels);
}
}
消费
import redis.clients.jedis.Jedis;
public class SubCustomer {
public static void main(String[] args) {
Thread thread =new Thread(()->{
Jedis jedis = new Jedis("192.168.81.132");
jedis.auth("password");
long start = System.currentTimeMillis();
Subscriber subscriber = new Subscriber();
while(true) {
jedis.subscribe(subscriber , "message_pub");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
if( (System.currentTimeMillis() - start) > 3600 * 1000) {
break;
}
}
jedis.close();
});
thread.start();
}
}
stream
生产者
import java.util.HashMap;
import java.util.Map;
import java.util.Random;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.StreamEntryID;
/**
* stream 生产者
*
*/
public class StreamProducter {
private final static String PASSWORD = "password";
public static void main(String[] args) {
Thread thread = new Thread(()->{
System.out.println(Thread.currentThread().getName());
Jedis jedis = new Jedis("192.168.81.132");
jedis.auth(PASSWORD);
String key = "key_2";
String groupName = "groupName";
String groupName2 = "groupName2";
if(jedis.exists(key)) {
jedis.del(key);
}
jedis.xgroupCreate(key,groupName, null, true);
jedis.xgroupCreate(key,groupName2, null, true);
long start = System.currentTimeMillis();
Map<String,String> map = null;
Random random = new Random();
StreamEntryID xadd = null;
while(true) {
map = new HashMap<>(4);
map.put(String.valueOf(random.nextInt(1000)), String.valueOf(random.nextInt(100)));
xadd = jedis.xadd(key,null, map);
System.out.println(xadd.toString());
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
if((System.currentTimeMillis() - start) > 3600 * 1000) {
break;
}
}
jedis.del(key);
jedis.close();
},"streamProducter-thread");
thread.start();
}
}
消费者
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import com.alibaba.fastjson.JSON;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.StreamEntry;
import redis.clients.jedis.StreamEntryID;
import redis.clients.jedis.StreamPendingEntry;
public class StreamCustomer {
private final static String PASSWORD = "password";
public static void main(String[] args) {
Thread thread = new Thread(()->{
long start = System.currentTimeMillis();
Jedis jedis = new Jedis("192.168.81.132",6379);
jedis.auth(PASSWORD);
String stream = "key_2";
String groupName = "groupName";
String customerName = "myk_customer";
Long xgroupDelConsumer = jedis.xgroupDelConsumer(stream, groupName, customerName);
HashMap<String,StreamEntryID> map = new HashMap<>();
StreamEntryID streamEntryID = new StreamEntryID();
map.put(stream, null);
Map.Entry<String,StreamEntryID> t = null ;
t = map.entrySet().iterator().next();
while(true) {
List<Entry<String, List<StreamEntry>>> list = jedis.xreadGroup(groupName, customerName, 2, 0, false, t);
if(list == null) {
System.out.println(customerName+"\t空---结束了");
}else {
Iterator<Entry<String, List<StreamEntry>>> iterator = list.iterator();
while(iterator.hasNext()) {
Entry<String, List<StreamEntry>> next = iterator.next();
System.out.println(customerName+"\tkey:"+next.getKey()+"\tmessage:"+JSON.toJSONString(next.getValue()));
List<StreamEntry> listValue = next.getValue();
for (StreamEntry streamEntry : listValue) {
StreamEntryID id = streamEntry.getID();
long xack = jedis.xack(next.getKey(), groupName, id);
System.out.println(customerName+"\txack:"+xack+"\tmessage:"+JSON.toJSONString(streamEntry.getFields()));
}
}
}
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
if( (System.currentTimeMillis()-start) > 3600*1000 ) {
break;
}
}
jedis.close();
});
Thread thread2 = new Thread(()->{
long start = System.currentTimeMillis();
Jedis jedis = new Jedis("192.168.81.132",6379);
jedis.auth(PASSWORD );
String stream = "key_2";
String groupName = "groupName2";
String customerName = "myk_customer2";
Long xgroupDelConsumer = jedis.xgroupDelConsumer(stream, groupName, customerName);
HashMap<String,StreamEntryID> map = new HashMap<>();
StreamEntryID streamEntryID = new StreamEntryID();
map.put(stream, null);
Map.Entry<String,StreamEntryID> t = null ;
t = map.entrySet().iterator().next();
while(true) {
List<Entry<String, List<StreamEntry>>> list = jedis.xreadGroup(groupName, customerName, 2, 0, false, t);
if(list == null) {
System.out.println(customerName+"\t空---结束了");
}else {
Iterator<Entry<String, List<StreamEntry>>> iterator = list.iterator();
while(iterator.hasNext()) {
Entry<String, List<StreamEntry>> next = iterator.next();
System.out.println(customerName+"\tkey:"+next.getKey()+"\tmessage:"+JSON.toJSONString(next.getValue()));
List<StreamEntry> listValue = next.getValue();
for (StreamEntry streamEntry : listValue) {
StreamEntryID id = streamEntry.getID();
// long xack = jedis.xack(next.getKey(), groupName, id);
long xack = 0;
System.out.println(customerName+"\txack:"+xack+"\tmessage:"+JSON.toJSONString(streamEntry.getFields()));
}
}
List<StreamPendingEntry> xpending = jedis.xpending(stream, groupName, null, null, 5, customerName);
Iterator<StreamPendingEntry> iterator2 = xpending.iterator();
while(iterator2.hasNext()) {
StreamPendingEntry next = iterator2.next();
StreamEntryID id = next.getID();
long xack = jedis.xack(stream, groupName, id);
System.out.println(customerName+"id:\t"+id+"\txpending:"+xack);
}
}
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
if( (System.currentTimeMillis()-start) > 3600*1000 ) {
break;
}
}
jedis.close();
});
thread.start();
thread2.start();
}
}