{"id":21685622,"url":"https://github.com/redis-field-engineering/redis-streams-java-dist","last_synced_at":"2026-02-21T11:30:55.339Z","repository":{"id":259523237,"uuid":"877902736","full_name":"redis-field-engineering/redis-streams-java-dist","owner":"redis-field-engineering","description":" Java library for Redis Streams providing a simplified developer experience and increased scalability","archived":false,"fork":false,"pushed_at":"2025-04-02T20:29:59.000Z","size":632,"stargazers_count":2,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-04-02T21:32:22.821Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":null,"has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/redis-field-engineering.png","metadata":{"files":{"readme":"README.adoc","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-10-24T12:48:32.000Z","updated_at":"2025-04-02T20:30:03.000Z","dependencies_parsed_at":"2024-10-26T07:14:54.450Z","dependency_job_id":"a9a793ec-f3ca-4f75-9dea-df09450bf4f8","html_url":"https://github.com/redis-field-engineering/redis-streams-java-dist","commit_stats":null,"previous_names":["redis-field-engineering/redis-streams-java-dist"],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/redis-field-engineering/redis-streams-java-dist","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/redis-field-engineering%2Fredis-streams-java-dist","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/redis-field-engineering%2Fredis-streams-java-dist/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/redis-field-engineering%2Fredis-streams-java-dist/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/redis-field-engineering%2Fredis-streams-java-dist/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/redis-field-engineering","download_url":"https://codeload.github.com/redis-field-engineering/redis-streams-java-dist/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/redis-field-engineering%2Fredis-streams-java-dist/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29679781,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-21T11:29:27.227Z","status":"ssl_error","status_checked_at":"2026-02-21T11:29:20.292Z","response_time":107,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-25T16:22:13.520Z","updated_at":"2026-02-21T11:30:55.331Z","avatar_url":"https://github.com/redis-field-engineering.png","language":null,"readme":":linkattrs:\n:project-owner:   redis-field-engineering\n:project-name:    redis-streams-java\n:project-group:   com.redis\n:project-version: 0.3.6\n:dist-repo:       redis-streams-java-dist\n:name:            Redis Streams Java\n:toc:\n:toc-title:\n:toc-placement!:\n\n= {name}\n\n{name} is a Java library that provides a topic abstraction over Redis streams.\nEach topic is backed by one or more Redis streams. As you publish messages to a topic, a new stream\nis automatically created as soon as the current stream grows beyond a predefined size. This allows\nstreams to scale linearly across the shards of your Redis cluster.\n\nThe library provides core functionality for writing to a distributed Redis Stream as well as reading\nfrom a distributed Redis Stream in Redis. This works in all Redis deployment scenarios:\n\n* A Pair of Redis Enterprise or Redis Cloud Active-Active Clusters\n* Redis Enterprise or Redis Cloud Instance.\n* Single Instance of Redis Stack\n\nIn fact the library takes special care to ensure that reading from a Consumer Group of a single topic across two Active-Active clusters\nis done so in a way that honors the ordering and pending entry list of the consumer group consistently.\n\n[discrete]\n== Table of Contents\ntoc::[]\n\n\n== Requirements\n\n{name} requires a https://javadoc.io/doc/redis.clients/jedis/5.0.1/redis/clients/jedis/JedisPooled.html[`JedisPooled`] connection object. You may want to tune your `JedisPooled` instance for your own needs.\n\n== Quick start\n\n== Installation\n\nTo run {name} in production, you'll need one of the following deployments:\n\n* https://redis.io/docs/stack/[Redis Stack]\n* https://redis.com/redis-enterprise-cloud/overview/[Redis Cloud]\n* https://redis.com/redis-enterprise-software/overview/[Redis Enterprise]\n\n=== {name} Connector\n\nNext, you'll need to install the {name} plugin and configure it.\n\n=== Redis installation\n\nFor a self-managed deployment, or for testing locally, install https://redis.io/docs/stack/[Redis Stack] or spin up a free https://redis.com/try-free/[Redis Cloud] instance.\nIf you need a fully-managed, cloud-based deployment of Redis on AWS, GCP, or Azure, see all the https://redis.com/redis-enterprise-cloud/overview/[Redis Cloud] offerings.\nFor deployment in your own private cloud or data center, consider https://redis.com/redis-enterprise-software/overview/[Redis Enterprise].\n\n== Documentation\n\n== Add the library to your project\n\nTo install the library simply add the following:\n\n=== Maven\nAdd the following to your `pom.xml` file:\n\n[source,xml]\n[subs=\"verbatim,attributes\"]\n.pom.xml\n----\n\u003cdependency\u003e\n    \u003cgroupId\u003e{project-group}\u003c/groupId\u003e\n    \u003cartifactId\u003e{project-name}\u003c/artifactId\u003e\n    \u003cversion\u003e{project-version}\u003c/version\u003e\n\u003c/dependency\u003e\n----\n\n=== Gradle\n\nAdd the following to your `build.gradle` file from the https://central.sonatype.com/artifact/com.redis/redis-streams-java[central repository]\n\n[source,groovy]\n[subs=\"attributes\"]\n.build.gradle\n----\ndependencies {\n    implementation '{project-group}:{project-name}:{project-version}'\n}\n----\n\n== Usage\n\n=== Components\n\nGenerically, there are three primary components of the streams library\n\n1. `TopicManager` - Oversees the topics, tracks the status of consumers within the library. \n2. `ConsumerGroup` - Manages and coordinates consumption from topics.\n3. `TopicProducer` - Produces messages for the topic.\n\n\n==== Jedis Connection\nTo connect any of these key components you will need a `JedisPooled` connection to Redis.\n\n==== TopicManager\n\nTo initialize the `TopicManager`, simply pass in your Jedis Connection along with a topic manager configuration to `createTopic`.\n\n\n```java\nJedisPooled jedis = new JedisPooled(\"redis://localhost:6379\");\nSerialTopicConfig config = new SerialTopicConfig(\"my-topic\");\nTopicManager topicManager = TopicManager.createTopic(jedis, config);\n```\n\nThis will create the topic manager, as well as creating the items in Redis required to support the topic.\n\n==== TopicProducer\n\nThe next step is to create a `TopicProducer`, to create one, simply pass in your Jedis Connection along with the topic name to the `TopicProducer` constructor.\n\n```java\nProducer producer = new TopicProducer(jedis, \"my-topic\");\n```\n\n==== ConsumerGroup\n\nThe final item to create is a `ConsumerGroup`, the consumer group is responsible for coordinating consumption of the topic. To create a `ConsumerGroup`, pass your Jedis Connection along with the topic name and your consumer name into the `ConsumerGroup` constructor\n\n```java\nConsumerGroup consumerGroup = new ConsumerGroup(jedis, \"my-topic\", \"test-group\");\n```\n\n== Producing messages\n\nTo add a message to the topic, simply pass a `Map\u003cString,String\u003e` into the `TopicProducer`\n\n```\nMap\u003cString, String\u003e msg = Map.of(\"temp\", \"81\",  \"humidity\", \"0.92\", \"city\", \"Satellite Beach\");\nproducer.produce(msg);\n```\n\n== Consuming messages\n\nTo consume messages, simply call `consume` on you consumer group, passing in your consumer name:\n\n```java\nTopicEntry entry = consumerGroup.consume(\"my-consumer\");\n```\n\nThe message contains:\n1. The message id (the monotonic id created by Redis when the message was produced)\n2. The Stream the message was read from\n3. The message itself\n\n=== Acknowledge Messages\n\nAfter you have consumed a message, you must then acknowledge it, to do so, simply call `acknowledge` passing in the `AckMessage` constructed from the `TopicEntry` received from consuming a message.\n\n```java\nTopicEntry entry = consumerGroup.consume(\"test-consumer\");\n// Some extra processing\n// ...\nconsumerGroup.acknowledge(new AckMessage(entry));\n```\n\n== Get Pending Messages\n\nIf your application is unable to acknowledge the message (for example if the process died during processing), the messages remain in a pending state, you can acquire any pending messages using the `TopicManager`.\nThen you can acknowledge those messages using the consumerGroup:\n\n```java\nList\u003cPendingEntry\u003e pendingEntryList = topicManager.getPendingEntries(\"my-group\", query);\nconsumerGroup.acknowledge(new AckMessage(pendingEntryList.get(0)));\n```\n\n== Checking Consumer Stats\n\nIf you want to keep an eye on what is going on with your topic, and the consumer groups within the topic, you can use the use the `TopicManager`'s `getConsumerGroupStats` method:\n\n```java\nConsumerGroupStatus stats = topicManager.getConsumerGroupStatus(\"my-group\");\nSystem.out.printf(\"Consumer Group Name: %s%n\", stats.getGroupName());\nSystem.out.printf(\"Consumer Group Topic Size: %d%n\", stats.getTopicEntryCount());\nSystem.out.printf(\"Consumer Group Pending Entries: %d%n\", stats.getPendingEntryCount());\nSystem.out.printf(\"Consumer Group Lag: %d%n\", stats.getConsumerLag());\n```\n\n== NOACK Consumer Group\n\nA `NoAckConsumerGroup` implementation exists which allows you to read from a stream in the context of a \nconsumer group with no need to acknowledge any messages that you retrieved from the stream. This is useful when\nyou want to ensure \"exactly once\" delivery semantics and are comfortable losing a message if something \nhappens after the entry is delivered. To utilize this, just initialize the `NoAckConsumerGroup`, and consume \nas you would with the normal `ConsumerGroup` the key difference is that there is no need to acknowledge any \n\n```java\nNoAckConsumerGroup noack = new NoAckConsumerGroup(jedis, \"my-topic\", \"no-ack-group\");\nTopicEntry entry = noack.consume(\"my-consumer\");\n// your apps processing\n```\n\n== Single Cluster PEL\n\nThere is also a \"Single Cluster PEL\" topic manager and consumer group. This implementation does not replicate\nthe Pending Entries List (PEL) across Cluster in an Active-Active configuration, making it more performant than its\nstandard counterpart for those Active Active deployments. The caveat is that your consumer group PEL will not be synchronized\nacross clusters, so you will not be able to claim any entries dropped outside of the original region of consumption.\n\nTo read without replicating the PEL, simply initialize the `SingleClusterPelConsumer` group and use it as you would with any\nother consumer group:\n\n```java\nSingleClusterPelConsumerGroup singleClusterPel = new SingleClusterPelConsumerGroup(jedis, \"my-topic\", \"pel-group\");\nTopicEntry entry = singleClusterPel.consume(\"my-consumer\");\n// your apps processing\nsingleClusterPel.acknowledge(new AckMessage(entry));\n```\n\n=== Consumer Group Stats and Pending Entries with Single Cluster PEL\n\nThe method for gather Consumer group stats and getting pending entries is naturally different with the Single Cluster PEL\nimplementation. You must therefore use a specialized `SingleCLusterPelTopicManager` to retrieve these e.g.:\n\n```java\nSingleClusterPelTopicManager singleClusterPelTopicManager = new SingleClusterPelTopicManager(jedis, config);\nPendingEntryQuery query = new PendingEntryQuery();\nquery.setCount(1);\nList\u003cPendingEntry\u003e pendingEntriesSingleCLuster = singleClusterPelTopicManager.getPendingEntries(\"pel-group\", query);\nConsumerGroupStatus consumerGroupStatsSingleCluster = singleClusterPelTopicManager.getConsumerGroupStatus(\"pel-group\");\n```\n\n\n== Support\n\n{name} is supported by Redis, Inc. for enterprise-tier customers as a 'Developer Tool' under the https://redis.io/legal/software-support-policy/[Redis Software Support Policy.] For non enterprise-tier customers we supply support for {name} on a good-faith basis.\nTo report bugs, request features, or receive assistance, please https://github.com/{project-owner}/{dist-repo}/issues[file an issue].\n\n== License\n\n{name} is licensed under the Business Source License 1.1. Copyright (C) 2024 Redis, Inc. See https://github.com/redis-field-engineering/{dist-repo}/blob/main/LICENSE.md[LICENSE] for details.\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fredis-field-engineering%2Fredis-streams-java-dist","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fredis-field-engineering%2Fredis-streams-java-dist","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fredis-field-engineering%2Fredis-streams-java-dist/lists"}