Exploring nimble networking
The network card enables the database server to exchange data with the outside world. This includes far more than web servers, spreadsheets, loading jobs, application servers, and other data consumers. The database server is part of a large continuum of activity, much of which will center around maintenance, management, and even filesystem availability.
Little of this other traffic involves PostgreSQL directly. Much happens in the background regardless of the database and its current workload. Yet even one mishandled network packet across an otherwise normal driver can render the entire server invisible to the outside world, or in extreme cases, even lead to a system panic and subsequent shutdown. On a busy database server, network cards can handle several terabytes of traffic on a daily basis; the margin of error for such a critical piece of hardware is exceptionally slim.
What's more, network bandwidth can easily be saturated by an aggressive backup strategy, which is something critical to a highly available database. For PostgreSQL systems utilizing streaming replication or WAL archival, that traffic contributes quite a bit of bandwidth to the overall picture. If our backups are delayed, or replicas sit idle waiting for network packets, our exposure to risk is high indeed.
That's not to say everything is doom and gloom! With the right network setup and accompanying hardware, there should be more than enough room for any and all traffic our database server needs. Let's explore all the copious options for connecting our database to the outside world, and making sure it stays there.
Getting ready
This is one of those times it pays to do research. At the time of this writing, the current high-speed network standards include 1 Gb/s, 10 Gb/s, 40 Gb/s, and even 100 Gb/s Ethernet. However, 40 Gb/s network cards are still extremely rare, and 100 Gb/s is generally reserved for fiber-based switches and data center use.
This means we will be covering 1 Gb/s and 10 Gb/s interfaces. While we will do our best to outline all important aspects of these technologies to simplify the process, we strongly encourage using the Internet to validate current availability and performance characteristics.
How to do it...
Let's begin with a few basic calculations. Look at these following numbers that represent an estimate of interface speed after accounting for overhead:
- 1000 Mb/s * B/10 b = 100 MB/s
- 10,000 Mb/s * B/10 b = 1,000 MB/s
Next, consider how many ways this will be distributed. If we have an existing PostgreSQL setup, follow these steps:
- Execute the following query to determine the number of existing replicas:
SELECT count(1)+1 AS streams FROM pg_stat_replication;
- Multiply streams by 160 for maximum MB/s needed by replication streams.
- Execute the following queries together in a psql connection during a busy time of day on a production database:
SELECT SUM(pg_stat_get_db_tuples_fetched(oid)) AS count1 FROM pg_database; SELECT pg_sleep(1); SELECT SUM(pg_stat_get_db_tuples_fetched(oid)) AS count2 FROM pg_database;
- Subtract the results of
count1
fromcount2
for the number of rows fetched from the database per second. - Divide the number of rows per second by 10,000 for MB/s used by PostgreSQL connections.
- Add MB/s for streams to MB/s for connections.
Without an existing database, follow these steps for some basic bandwidth numbers:
- Multiply the desired number of PostgreSQL replicas by 160 for the maximum MB/s needed by replication streams.
- Assume one WAL stream for an off-site disaster recovery database copy.
- Start with at least one live hot streaming standby copy.
- Include any additional database mirrors.
- Estimate the active client count as discussed in Picking a Processor.
- Multiply the active client count estimate by 5 for MB/s used by PostgreSQL connections.
- Add MB/s for streams to MB/s for connections.
No matter which checklist we follow, we should double the final tally.
How it works...
If we have an existing database, there is a wealth of statistical information at our fingertips. The first query we ran gave us a slightly inflated count of copies of our database. For each copy, data must be transferred from the database to another server. This data is based on PostgreSQL WAL output, and these files are 16 MB each. A busy server can produce more than ten of these per second, so we multiply the count of streams by 160 to produce an aggressive amount of network overhead used by database replicas. As usual, this may be overzealous; it's always best to observe an actual system to measure maximum WAL segments generated during heavy write loads.
Note
In PostgreSQL 9.2 and higher, database replicas can stream from other database replicas. This means network traffic can be distributed better among streaming clients, reducing network bandwidth pressure on production systems. PostgreSQL 9.2 also allows direct backup of streaming replicas. This means one or two replicas may be the most the production database ever needs to supply with WAL traffic.
For the next set of numbers, we need to know how much data database connections commonly retrieve. PostgreSQL tracks the number of table rows fetched, but it's a cumulative total. By waiting until a busy time of day and asking the database how many rows have been fetched before and after a one-second wait, we know how many rows are fetched per second.
However, we still don't know how many bytes these rows consume. A good estimate of this is 100 bytes per row. Then we only have to multiply the number of rows by 100 to find the amount of bandwidth we would need. So why do we divide by 10,000? What's 10,000 multiplied by 100? One million. On dividing by 10,000, we produce the number of megabytes per second those tuple fetches probably used.
Tip
If an average of 100 bytes per row isn't good enough, we can connect to one of our primary databases and ask what the average is. Use this query:
SELECT sum(pg_relation_size(oid)) / sum(reltuples) FROM pg_class;
By adding the amount of streaming traffic to the amount of connection traffic, we have a good, if slightly inflated, idea of how much bandwidth the server needs.
Without a working database to go by, we need to use a few guesses instead. Luckily, the number of streams for a reliable database infrastructure starts at two: one for a live standby, and one for an off-site archive. Each additional desired mirror should increase this total. Again, we multiply by 160 to obtain the maximum megabytes per second that all these streams are likely to require.
The amount of bandwidth client connections use is slightly harder to estimate. However, if we worked through previous chapter sections, we have a CPU estimate, which also tells us the maximum number of database clients the server can reliably support. If we take that value and multiply by five, that provides a rough value in megabytes per second as well.
Again, we just add those two totals together, and we know the minimum speed of our network.
Finally, we multiply the final tally by two, to account for any unknown maintenance, backup, and filesystem synchronization overhead.
There's more...
Besides producing an estimate through some simple calculations, we also want to make note of a few other networking details.
A networking example
This may be easier to visualize with a real example. Let's start with a very active database that has one streaming replica, and one off-site archive. Further more, connected clients regularly fetch five-million rows per second. Now, let's go through our steps:
- 2 * 160 = 320 MB/s
- 5,000,000 / 10,000 = 50 MB/s
- 320 + 50 = 370 MB/s
- 370 * 2 = 740 MB/s
That's a very high value! A 1 Gb/s interface can only supply 100 MB/s at most, so we would need eight of those to produce the necessary bandwidth. Yet a 10 Gb/s interface can supply 1000 MB/s, so it can easily handle 740 MB/s, and have room to spare. Would we rather have eight network cables coming out of our server, or one?
Remember redundancy
One of the first things this chapter suggested was to consider extra inventory. What we haven't really covered yet involves online backups. Most server-class motherboards include not just one, but two on-board network modules. Each module commonly provides four Ethernet interfaces.
Usually each interface is considered separate, and two interfaces from each module are connected to two switches in the data center. This allows server administrators to seamlessly perform maintenance on either switch without disrupting our network traffic. Further more, if a switch or network module fails, there's always a backup available.
In our working example, we would need eight 1 Gb/s interfaces to avoid experiencing network congestion. However, we've already used four of our eight available interfaces simply to satisfy basic server hosting requirements. That doesn't leave enough available capacity, and as a consequence, this server would experience a network bottleneck.
This would not be the case with a 10 Gb/s interface. Each of the interfaces connected to redundant switches can carry the entire network requirements of the server.
Save the research
We suggested doing research on 1 Gb/s and 10 Gb/s network cards. Well, don't do too much. It's very likely the infrastructure department already has a standard server profile for high-bandwidth systems. This is primarily due to the fact 10 Gb/s is a very complicated standard compared to 1 Gb/s or lower. There are several different cable types available along with complimentary network modules, one or more of which are probably already deployed in the data center.
Just make sure that the infrastructure knows to allocate high-bandwidth resources if our calculations call for it.
See also
- To read more about how 10-gigabit Ethernet works, please visit the following URL: http://en.wikipedia.org/wiki/10