Scaling PostgreSQL With GridSQL

8,562 views

Published on

GridSQL is commonly thought of as a replication solution along the likes of Slony and Bucardo, but the open source GridSQL project actually allows PostgreSQL queries to be parallelized across many servers allowing performance to scale nearly linearly. In this session, we will discuss the advantages to using GridSQL for large multi-terabyte data warehouses and how to design your PostgreSQL schemas and queries to leverage GridSQL. We will dig into how GridSQL plans a query capable of spanning multiple PostgreSQL servers and executes across those nodes. We will delve into some performance expectations and where GridSQL should be deployed.

Published in: Technology

Scaling PostgreSQL With GridSQL

  1. 1. <ul>Scaling PostgreSQL with GridSQL </ul>
  2. 2. <ul>Who Am I? </ul><ul><li>Jim Mlodgenski </li><ul><li>Co-organizer of NYCPUG
  3. 3. Founder of Cirrus Technologies
  4. 4. Former Chief Architect of EnterpriseDB </li></ul></ul>
  5. 5. <ul>Agenda </ul><ul><li>What is GridSQL?
  6. 6. Architecture
  7. 7. Query Flow
  8. 8. Scaling
  9. 9. Limitations </li></ul>
  10. 10. <ul>What is GridSQL? </ul><ul><li>“ Shared-Nothing”, distributed data architecture. </li><ul><li>Leverage the power of multiple commodity servers while appearing as a single database to the application </li></ul><li>Essentially... </li><ul><li>Open Source
  11. 11. Greenplum, Netezza or Teradata </li></ul></ul>
  12. 12. <ul>GridSQL Details </ul><ul><li>Designed for Parallel Querying
  13. 13. Not just “Read-Only”, can execute UPDATE, DELETE
  14. 14. Data Loader for parallel loading
  15. 15. Standard connectivity via PostgreSQL compatible connectors: JDBC, ODBC, ADO.NET, libpq (psql) </li></ul>
  16. 16. <ul>What GridSQL is not? </ul><ul><li>A replication solution like Slony or Bucardo
  17. 17. A high availability solution like Streaming Replication in PostgreSQL 9.0
  18. 18. A scalable transactional solution like PostgresXC
  19. 19. An elastic, eventually consistent NoSQL database </li></ul>
  20. 20. <ul>Configuration </ul><ul><li>Can be configured for multiple logical “nodes” per physical server </li><ul><li>Take advantage of multi-core processors </li></ul><li>Tables may be either replicated or partitioned
  21. 21. Replicated tables for static lookup data or dimensions </li><ul><li>Partitioned tables for large fact tables </li></ul></ul>
  22. 22. <ul>Partitioning </ul><ul><li>Tables may simultaneously use GridSQL Partitioning with Constraint Exclusion Partitioning </li><ul><li>Large queries scan a much smaller subset of data by using subtables
  23. 23. Since each subtable is also partitioned across nodes, they are scanned in parallel
  24. 24. Queries execute much faster </li></ul></ul>
  25. 25. <ul>Architecture </ul><ul><li>Loosely coupled, shared-nothing architecture
  26. 26. Data repositories </li><ul><li>Metadata database
  27. 27. GridSQL database </li></ul><li>GridSQL processes </li><ul><li>Central coordinator
  28. 28. Agents </li></ul></ul>
  29. 29. <ul>Query Optimization </ul><ul><li>Cost Based Optimizer </li><ul><li>Takes into account Row Shipping (expensive) </li></ul><li>Looks for joins with replicated tables </li><ul><li>Can be done locally
  30. 30. Looks for joins between tables on partitioned columns </li></ul></ul>
  31. 31. <ul>Aggregation </ul><ul><li>First set of aggregates done in parallel at the nodes
  32. 32. Like groups of intermediate results shipped to same target node
  33. 33. Second aggregation done in parallel
  34. 34. Coordinator streams in node results, combining on the fly and sending to client result set, performing a merge sort if ORDER BY present </li></ul>
  35. 35. <ul>Two Phase Aggregation </ul><ul><li>SUM </li><ul><li>SUM(stat1)
  36. 36. SUM2(SUM(stat1) </li></ul><li>AVG </li><ul><li>SUM(stat1) / COUNT(stat1)
  37. 37. SUM2 (SUM(stat1)) / SUM2 (COUNT(stat1)) </li></ul></ul>
  38. 38. <ul>Creating Tables </ul><ul><li>Tables can be partitioned or replicated </li></ul>CREATE TABLE region (r_regionkey INTEGER NOT NULL, r_name CHAR(25) NOT NULL, r_comment VARCHAR(152)) REPLICATED;
  39. 39. <ul>Creating Tables </ul>CREATE TABLE orders ( o_orderkey INTEGER NOT NULL, o_custkey INTEGER NOT NULL, o_orderstatus CHAR(1) NOT NULL, o_totalprice DECIMAL(15,2) NOT NULL, o_orderdate DATE NOT NULL, o_orderpriority CHAR(15) NOT NULL, o_clerk CHAR(15) NOT NULL, o_shippriority INTEGER NOT NULL, o_comment VARCHAR(79) NOT NULL) PARTITIONING KEY o_orderkey ON ALL;
  40. 40. <ul>DBT3 : Query 1 </ul>SELECT l_returnflag, l_linestatus, sum(l_quantity) as sum_qty, sum(l_extendedprice) as sum_base_price, sum(l_extendedprice * (1 - l_discount)) as sum_disc_price, sum(l_extendedprice * (1 - l_discount) * (1 + l_tax)) as sum_charge, avg(l_quantity) as avg_qty, avg(l_extendedprice) as avg_price, avg(l_discount) as avg_disc, count(*) as count_order FROM lineitem WHERE l_shipdate <= date'1998-12-01' - interval '90 days' GROUP BY l_returnflag, l_linestatus ORDER BY l_returnflag, l_linestatus; Results l_returnflag | l_linestatus | sum_qty | sum_base_price | ... | count_order --------------+--------------+----------+----------------+ ... +------------- A | F | 37734104 | 56586654000 | ... | 1478493 N | F | 991417 | 1487505700 | ... | 38854 N | O | 74473520 | 111717540000 | ... | 2920374 R | F | 37719752 | 56567792000 | ... | 1478870 (4 rows)
  41. 41. Query 1 – Execution (no Agents) Go to Animation Slide
  42. 42. <ul>DBT3 : Query 7 </ul>Results supp_nation | cust_nation | l_year | revenue ---------------------------+---------------------------+--------+-------------------- GERMANY | UNITED STATES | 1995 | 51883178.038909949 GERMANY | UNITED STATES | 1996 | 52528107.076993272 UNITED STATES | GERMANY | 1995 | 51546631.033109233 UNITED STATES | GERMANY | 1996 | 53108668.056805529 (4 rows) SELECT supp_nation, cust_nation, l_year, sum(volume) as revenue FROM (SELECT n1.n_name as supp_nation, n2.n_name as cust_nation, extract(year from l_shipdate) as l_year, l_extendedprice * (1 - l_discount) as volume FROM supplier, lineitem, orders, customer, nation n1, nation n2 WHERE s_suppkey = l_suppkey AND o_orderkey = l_orderkey AND c_custkey = o_custkey AND s_nationkey = n1.n_nationkey AND c_nationkey = n2.n_nationkey AND ((n1.n_name = 'GERMANY' and n2.n_name = 'UNITED STATES') or (n1.n_name = 'UNITED STATES' and n2.n_name = 'GERMANY')) AND l_shipdate between date '1995-01-01' and date '1996-12-31' ) AS shipping GROUP BY supp_nation, cust_nation, l_year ORDER BY supp_nation, cust_nation, l_year;
  43. 43. Query 7 – Execution (with Agents) Go to Animation Slide
  44. 44. <ul>Scalability </ul>
  45. 45. <ul>Scalability </ul><ul><li>A few DBT3 queries on Amazon EC2 </li><ul><li>Using PostgreSQL 9.0 </li></ul></ul>
  46. 46. <ul>Scalability </ul>SELECT l_returnflag, l_linestatus, sum(l_quantity) as sum_qty, sum(l_extendedprice) as sum_base_price, sum(l_extendedprice * (1 - l_discount)) as sum_disc_price, sum(l_extendedprice * (1 - l_discount) * (1 + l_tax)) as sum_charge, avg(l_quantity) as avg_qty, avg(l_extendedprice) as avg_price, avg(l_discount) as avg_disc, count(*) as count_order FROM lineitem WHERE l_shipdate <= date'1998-12-01' - interval '90 days' GROUP BY l_returnflag, l_linestatus ORDER BY l_returnflag, l_linestatus;
  47. 47. <ul>Scalability </ul>SELECT supp_nation, cust_nation, l_year, sum(volume) as revenue FROM (SELECT n1.n_name as supp_nation, n2.n_name as cust_nation, extract(year from l_shipdate) as l_year, l_extendedprice * (1 - l_discount) as volume FROM supplier, lineitem, orders, customer, nation n1, nation n2 WHERE s_suppkey = l_suppkey AND o_orderkey = l_orderkey AND c_custkey = o_custkey AND s_nationkey = n1.n_nationkey AND c_nationkey = n2.n_nationkey AND ((n1.n_name = 'GERMANY' and n2.n_name = 'UNITED STATES') or (n1.n_name = 'UNITED STATES' and n2.n_name = 'GERMANY')) AND l_shipdate between date '1995-01-01' and date '1996-12-31' ) AS shipping GROUP BY supp_nation, cust_nation, l_year ORDER BY supp_nation, cust_nation, l_year;
  48. 48. <ul>Limitations </ul><ul><li>SQL Support </li></ul><ul><ul><li>Uses its own parser and optimizer so: </li><ul><li>No Window Functions
  49. 49. No Stored Procedures
  50. 50. No Full Text Search
  51. 51. No Spatial </li></ul></ul></ul>
  52. 52. <ul>Transaction Performance </ul><ul><li>Single row Insert, Update, or Delete are slow compared to a single PostgreSQL instance </li><ul><li>The data must make an additional network trip to be committed
  53. 53. All partitioned rows must be hashed to be mapped to the proper node
  54. 54. All replicated rows must be committed to all nodes </li></ul><li>Use “gs-loader” for bulk loading for better performance </li></ul>
  55. 55. <ul>High Availability </ul><ul><li>No heartbeat or fail-over control in the coordinator </li><ul><li>High Availability for each PostgreSQL node must be configured separately
  56. 56. Streaming replication can be ideal for this </li></ul><li>Getting a consistent backup of the entire GridSQL database is difficult </li><ul><li>Must ensure there are no transaction are occurring
  57. 57. Backup each node separately </li></ul></ul>
  58. 58. <ul>Adding Nodes </ul><ul><li>Requires Downtime </li><ul><li>Data must be manually reloaded to partition the data to the new node </li></ul><li>With planning, the process can be fast with no mapping of data </li><ul><li>Run multiple PostgreSQL instances on each physical server and move the PostgreSQL instances to new hardware as needed </li></ul></ul>
  59. 59. <ul>Interesting Side Note </ul><ul><li>GridSQL scales well in a cloud environment
  60. 60. The results are dependent on the cloud vendor </li></ul>
  61. 61. <ul>Summary </ul><ul><li>GridSQL can improve performance tremendously of PostgreSQL queries
  62. 62. GridSQL can scale linearly as more nodes are added
  63. 63. GridSQL is open source so if the limitations are an issue,
  64. 64. submit a patch </li></ul>
  65. 65. <ul>Download GridSQL at: http://sourceforge.net/projects/gridsql/ </ul><ul>Jim Mlodgenski <ul>Email: [email_address] Twitter: @jim_mlodgenski </ul></ul>

×