GithubHelp home page GithubHelp logo

binidxaba / pgmq Goto Github PK

View Code? Open in Web Editor NEW

This project forked from tembo-io/pgmq

0.0 0.0 0.0 424 KB

A lightweight message queue. Like AWS SQS and RSMQ but on Postgres.

License: PostgreSQL License

Python 13.10% Rust 81.40% Makefile 0.80% Dockerfile 0.25% PLpgSQL 4.44%

pgmq's Introduction

Postgres Message Queue (PGMQ)

A lightweight message queue. Like AWS SQS and RSMQ but on Postgres.

Static Badge

Features

  • Lightweight - Built with Rust and Postgres only
  • Guaranteed "exactly once" delivery of messages to a consumer within a visibility timeout
  • API parity with AWS SQS and RSMQ
  • Messages stay in the queue until explicitly deleted
  • Messages can be archived, instead of deleted, for long-term retention and replayability
  • High performance operations with index-only scans

Table of Contents

Installation

The fastest way to get started is by running the Tembo docker image, where PGMQ comes pre-installed.

docker run -d --name postgres -e POSTGRES_PASSWORD=postgres -p 5432:5432 quay.io/tembo/pgmq-pg:latest

If you'd like to build from source, you can follow the instructions in CONTRIBUTING.md.

Client Libraries

Community

SQL Examples

# Connect to Postgres
psql postgres://postgres:[email protected]:5432/postgres
-- create the extension
CREATE EXTENSION pgmq;

Creating a queue

Every queue is its own table in Postgres. The table name is the queue name prefixed with pgmq_. For example, pgmq_my_queue is the table for the queue my_queue.

-- creates the queue
SELECT pgmq_create('my_queue');
 pgmq_create
-------------

(1 row)

Send two messages

-- messages are sent as JSON
SELECT * from pgmq_send('my_queue', '{"foo": "bar1"}');
SELECT * from pgmq_send('my_queue', '{"foo": "bar2"}');

The message id is returned from the send function.

 pgmq_send
-----------
         1
(1 row)

 pgmq_send
-----------
         2
(1 row)

Read messages

Read 2 message from the queue. Make them invisible for 30 seconds. If the messages are not deleted or archived within 30 seconds, they will become visible again and can be read by another consumer.

SELECT * from pgmq_read('my_queue', 30, 2);
 msg_id | read_ct |          enqueued_at          |              vt               |     message
--------+---------+-------------------------------+-------------------------------+-----------------
      1 |       1 | 2023-08-16 08:37:54.567283-05 | 2023-08-16 08:38:29.989841-05 | {"foo": "bar1"}
      2 |       1 | 2023-08-16 08:37:54.572933-05 | 2023-08-16 08:38:29.989841-05 | {"foo": "bar2"}

If the queue is empty, or if all messages are currently invisible, no rows will be returned.

SELECT * from pgmq_read('my_queue', 30, 1);
 msg_id | read_ct | enqueued_at | vt | message
--------+---------+-------------+----+---------

Pop a message

-- Read a message and immediately delete it from the queue. Returns `None` if the queue is empty.
SELECT * from pgmq_pop('my_queue');
 msg_id | read_ct |          enqueued_at          |              vt               |     message
--------+---------+-------------------------------+-------------------------------+-----------------
      1 |       1 | 2023-08-16 08:37:54.567283-05 | 2023-08-16 08:38:29.989841-05 | {"foo": "bar1"}

Archive a message

Archiving a message removes it from the queue, and inserts it to the archive table.

Archive message with msg_id=2.

SELECT * from pgmq_archive('my_queue', 2);
 pgmq_archive
--------------
 t
(1 row)
SELECT * from pgmq_my_queue_archive;
 msg_id | read_ct |         enqueued_at          |          archived_at          |              vt               |     message
--------+---------+------------------------------+-------------------------------+-------------------------------+-----------------
      2 |       1 | 2023-04-25 00:55:40.68417-05 | 2023-04-25 00:56:35.937594-05 | 2023-04-25 00:56:20.532012-05 | {"foo": "bar2"}```

Delete a message

Send another message, so that we can delete it.

SELECT * from pgmq_send('my_queue', '{"foo": "bar3"}');
 pgmq_send
-----------
        3
(1 row)

Delete the message with id 3 from the queue named my_queue.

SELECT pgmq_delete('my_queue', 3);
 pgmq_delete
-------------
 t
(1 row)

Drop a queue

Delete the queue my_queue.

SELECT pgmq_drop_queue('my_queue');
 pgmq_drop_queue
-----------------
 t
(1 row)

Configuration

Partitioned Queues

You will need to install pg_partman if you want to use pgmq partitioned queues.

pgmq queue tables can be created as a partitioned table by using pgmq_create_partitioned(). pg_partman handles all maintenance of queue tables. This includes creating new partitions and dropping old partitions.

Partitions behavior is configured at the time queues are created, via pgmq_create_partitioned(). This function has three parameters:

queue_name: text: The name of the queue. Queues are Postgres tables prepended with pgmq_. For example, pgmq_my_queue.

partition_interval: text - The interval at which partitions are created. This can be either any valid Postgres Duration supported by pg_partman, or an integer value. When it is a duration, queues are partitioned by the time at which messages are sent to the table (enqueued_at). A value of 'daily' would create a new partition each day. When it is an integer value, queues are partitioned by the msg_id. A value of '100' will create a new partition every 100 messages. The value must agree with retention_interval (time based or numeric). The default value is daily.

retention_interval: text - The interval for retaining partitions. This can be either any valid Postgres Duration supported by pg_partman, or an integer value. When it is a duration, partitions containing data greater than the duration will be dropped. When it is an integer value, any messages that have a msg_id less than max(msg_id) - retention_interval will be dropped. For example, if the max msg_id is 100 and the retention_interval is 60, any partitions with msg_id values less than 40 will be dropped. The value must agree with partition_interval (time based or numeric). The default is '5 days'. Note: retention_interval does not apply to messages that have been deleted via pgmq_delete() or archived with pgmq_archive(). pgmq_delete() removes messages forever and pgmq_archive() moves messages to the corresponding archive table forever (for example, pgmq_my_queue_archive).

In order for automatic partition maintenance to take place, several settings must be added to the postgresql.conf file, which is typically located in the postgres DATADIR. pg_partman_bgw.interval in postgresql.conf. Below are the default configuration values set in Tembo docker images.

Add the following to postgresql.conf. Note, changing shared_preload_libraries requires a restart of Postgres.

pg_partman_bgw.interval sets the interval at which pg_partman conducts maintenance. This creates new partitions and dropping of partitions falling out of the retention_interval. By default, pg_partman will keep 4 partitions "ahead" of the currently active partition.

shared_preload_libraries = 'pg_partman_bgw' # requires restart of Postgres
pg_partman_bgw.interval = 60
pg_partman_bgw.role = 'postgres'
pg_partman_bgw.dbname = 'postgres'

Visibility Timeout (vt)

pgmq guarantees exactly once delivery of a message within a visibility timeout. The visibility timeout is the amount of time a message is invisible to other consumers after it has been read by a consumer. If the message is NOT deleted or archived within the visibility timeout, it will become visible again and can be read by another consumer. The visibility timeout is set when a message is read from the queue, via pgmq_read(). It is recommended to set a vt value that is greater than the expected time it takes to process a message. After the application successfully processes the message, it should call pgmq_delete() to completely remove the message from the queue or pgmq_archive() to move it to the archive table for the queue.

✨ Contributors

Thanks goes to these incredible people:

pgmq's People

Contributors

chuckhend avatar v0idpwn avatar ianstanton avatar vrmiguel avatar craigpangea avatar sjmiller609 avatar russellkemmit avatar dependabot[bot] avatar ddorian avatar yrashk avatar samay-sharma avatar ryw avatar rzavalet avatar pabloem avatar mkrisher avatar kianmeng avatar pbzweihander avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.