Connect an application
The YugabyteDB ruby-pg smart driver is a Ruby driver for YSQL based on ged/ruby-pg, with additional connection load balancing features.
The driver makes an initial connection to the first contact point provided by the application to discover all the nodes in the cluster. If the driver discovers stale information (by default, older than 5 minutes), it refreshes the list of live endpoints with the next connection attempt.
YugabyteDB Aeon
To use smart driver load balancing features when connecting to clusters in YugabyteDB Aeon, applications must be deployed in a VPC that has been peered with the cluster VPC. For applications that access the cluster from outside the VPC network, either keep the load balancing features disabled (default setting) or use the upstream PostgreSQL driver instead; in this case, the cluster performs the load balancing. For more information, refer to Using smart drivers with YugabyteDB Aeon.CRUD operations
The following sections demonstrate how to perform common tasks required for Ruby application development using the YugabyteDB ruby-pg smart driver APIs.
Prerequisites
Install the YugabyteDB ruby-pg smart driver (yugabytedb-ysql
gem) using the following command:
$ gem install yugabytedb-ysql -- --with-pg-config=<yugabyte-install-dir>/postgres/bin/pg_config
Step 1: Import the driver package
Import the YugabyteDB ruby-pg driver module by adding the following import statement in your Ruby code:
#!/usr/bin/env ruby
require 'ysql'
Step 2: Set up the database connection
Ruby applications can connect to the YugabyteDB database using the YSQL.connect()
APIs. The ysql
module includes all the common functions or structs required for working with YugabyteDB.
Use the YSQL.connect()
method to create a connection object for the YugabyteDB database. This can be used to perform DDLs and DMLs against the database.
The following table describes the connection parameters required to connect, including smart driver parameters for uniform and topology load balancing.
Parameter | Description | Default |
---|---|---|
host | Host name of the YugabyteDB instance. You can also enter multiple addresses. | localhost |
port | Listen port for YSQL | 5433 |
user | User connecting to the database | yugabyte |
password | User password | yugabyte |
dbname | Database name | yugabyte |
load_balance | Enables uniform load balancing | false |
topology_keys | Enables topology-aware load balancing. Specify comma-separated geo-locations in the form cloud.region.zone:priority . Ignored if load_balance is false. |
Empty |
yb_servers_refresh_interval | The interval (in seconds) to refresh the servers list; ignored if load_balance is false |
300 |
fallback_to_topology_keys_only | If set to true and topology_keys are specified, the driver only tries to connect to nodes specified in topology_keys |
false |
failed_host_reconnect_delay_secs | Time (in seconds) to wait before trying to connect to failed nodes. When the driver is unable to connect to a node, it marks the node as failed using a timestamp, and ignores the node when trying new connections until this time elapses. | 5 |
The load_balance
property supports the following additional values: any (alias for 'true'), only-primary, only-rr, prefer-primary, and prefer-rr. See Node type-aware load balancing.
The following is an example of enabling uniform load balancing via connection string:
yburl = "postgresql://yugabyte:yugabyte@127.0.0.1:5433/yugabyte?load_balance=true"
connection = YSQL.connect(yburl)
The following is a code snippet for connecting to YugabyteDB by specifying the connection properties as key-value pairs:
connection = YSQL.connect(host: 'localhost', port: '5433', dbname: 'yugabyte',
user: 'yugabyte', password: 'yugabyte',
load_balance: 'true', yb_servers_refresh_interval: '10')
The following is an example connection string for connecting to YugabyteDB with topology-aware load balancing, and including a fallback placement:
yburl = "postgresql://yugabyte:yugabyte@127.0.0.1:5433/yugabyte?load_balance=true&topology_keys=cloud1.region1.zone1:1,cloud1.region1.zone2:2"
After the driver establishes the initial connection, it fetches the list of available servers from the cluster, and load balances subsequent connection requests across these servers.
Use multiple addresses
You can specify multiple hosts in the connection string to provide alternative options during the initial connection in case one of the nodes is unavailable.
yb_servers()
YSQL function.Delimit the addresses using commas, as follows:
yburl = "postgresql://yugabyte:yugabyte@127.0.0.1:5433,127.0.0.2:5433,127.0.0.3:5433/yugabyte?load_balance=true"
connection = YSQL.connect(yburl)
Use SSL
For a YugabyteDB Aeon cluster, or a YugabyteDB cluster with SSL/TLS enabled, set the following SSL-related properties while creating a connection.
Parameter | Description |
---|---|
sslmode | SSL mode used for the connection ('prefer', 'require', 'verify-ca', 'verify-full') |
sslrootcert | Path to the root certificate on your computer. For YugabyteDB Aeon, this would be the CA certificate file downloaded as root.crt . |
For example:
conn = YSQL.connect(host: '127.0.0.1', port: '5433', dbname: 'yugabyte', user: 'yugabyte',
password: 'yugabyte', load_balance: 'true',
sslmode: 'verify-full', sslrootcert: '/home/centos/root.crt')
Step 3: Write your application
Create a file yb-sql-helloworld.rb
and add the following content:
#!/usr/bin/env ruby
require 'ysql'
begin
# If you have a read-replica cluster and want to balance connections
# across only read replica nodes, set the load_balance property to 'only-rr'.
# Setting yb_servers_refresh_interval to '0' ensures that the driver refreshes
# the list of server before every connection attempt.
conn = YSQL.connect(host: '127.0.0.1', port: '5433', dbname: 'yugabyte', user: 'yugabyte',
password: 'yugabyte', load_balance: 'true',
yb_servers_refresh_interval: '0')
# Create table
conn.exec ("CREATE TABLE employee (id int PRIMARY KEY, \
name varchar, age int, \
language varchar)");
puts "Created table employee\n";
# Insert a row
conn.exec ("INSERT INTO employee (id, name, age, language) \
VALUES (1, 'John', 35, 'Ruby')");
puts "Inserted data (1, 'John', 35, 'Ruby')\n";
# Query the row
rs = conn.exec ("SELECT name, age, language FROM employee WHERE id = 1");
rs.each do |row|
puts "Query returned: %s %s %s" % [ row['name'], row['age'], row['language'] ]
end
rescue YSQL::Error => e
puts e.message
ensure
rs.clear if rs
conn.close if conn
end
Run the application
Run the application yb-sql-helloworld.rb
using the following command:
./yb-sql-helloworld.rb
You should see the following output.
Created table employee
Inserted data (1, 'John', 35, 'Ruby')
Query returned: John 35 Ruby