Solving the C20K Problem: 
PHP Performance and Scalability
Kuassi Mensah, Group Product Manager 
Oracle Corporation
The C20K Problem 
Genesis: the C10K Problem

• Circa 2003: “How to write a server which can handle 
  10.000 parallel connections”
• http://...
The C20K Problem

• Can a single commodity database server handle 20K 
  simultaneous PHP users? 

Solving C20K with Built­In Database  
    Mechanisms in PHP
•   Database Resident Connection Pool
•   Query Change Notific...
<Insert Picture Here>

Database Resident 
 Connection Pool
PHP Lacks Proper Connection Pool

Current choices: 
2. Persistent Connections
     •      Connection not automatically clo...
Database Resident Connection Pool  
                                     Dedicated servers
Connection           Connection...
Database Resident Connection Pool

 • Pools a set of dedicated servers on each database
 • Designed primarily...
DRCP in Action – PHP Connection
                                                        Pooled Database 
DRCP in Action – Closing Connection
                                               Pooled Database 
DRCP in Action – After Close
                                          Pooled Database 
Configuring and Starting DRCP 

•       Configure the Pool (Optional) 
      SQL> execute dbms_connection_pool.configure_p...
C20K, Yes We Did!
 PHP DRCP Benchmark
• PHP script
  • connect, query, disconnect, sleep 1 second
• Database Server
  • Du...
C20K, Yes We Did!
PHP DRCP Benchmark ­ Throughput
C20K, Yes We Did!
PHP DRCP Benchmark ­ Memory
<Insert Picture Here>

Query Change Notification
Built­in Query Change Notification 

Problem to solve:
Be notified when changes in the database invalidates 
an existing q...
<Insert Picture Here>

Client­Side Query Result Cache
query = quot;select name, address, phone, acctbal from custumer,
nation where c_nationkey= n_nationkey;
key = m...
Built­in Client Query Result Cache  
$query = quot;select /*+ RESULT_CACHE */ name,
address, phone, acctbal from customer,...
Configuring Client Query Result Cache 

1/ Configure the Cache
    Database Server Configuration (init.ora)
Client Query Result Cache
            5­8 x Faster









       10    ...
<Insert Picture Here>

Scaling with Stored Procedures
Stored Procedures instead of Multiple 
Unique Statements
                      Stored Procedures (PL/SQL or Java)
PHP Bulk Insert  

function do_transactional_insert($conn, $array)
    $s = oci_parse($conn,
           'insert into pta...
PHP Bulk Insert with Stored Procedure

function do_bulk_insert($conn, $array)
    $s = oci_parse($conn,
PL/SQL Stored Proc. (Bulk insert)
create or replace package mypkg as
 type arrtype is table of varchar2(20)
    index by p...
Using Java Stored Procedures in PHP 

•    Secure Credit­Card Processing     • Implement Parsers for various File 
<Insert Picture Here>

Database Built­in Partitioning
Built­in Partitioning 

Inventory            Items
<Insert Picture Here>

Scaling Very Complex SQL 
Scaling Very Complex SQL Queries 

Problem to Solve: Query Sales and Quantity by Year,
Department, Class and Country

The ...
Built­in OLAP Engine
Cube Organized Materialized Views
  Transparent to SQL Queries

                                            Materialized V...
<Insert Picture Here>

Scaling with Advanced Data 
Scaling w. Advanced Data Compression
             Going Green 
Database Failover
Oracle Database 11g RAC 
Shared Disk Architecture
Fast Application Notification of Events

• Pub/Sub Event Notification (AQ based)
• High Availability feature for PHP with ...
Database Failover – Application View

              Fast Connection Failover

  Invalid Connections              Valid...
Configuring Fast Application 
 Notification for PHP
• High Availability feature with RAC or DG
• Usable with or without DR...
Database Failover in PHP 

When DB node or network fails
  • Database generates FAN events
  • Oracle error returned witho...
C(N*20)K Using DRCP and RAC

• Scale your database horizontally to N*C20K with N 
  RAC nodes!!
• DRCP starts on all RAC i...
<Insert Picture Here>

      Case Study 
Community Connect Inc.  
Xtreme Scalability
   Web Scale PHP Deployment 
• 19+ million users
• 500+ millions pages views
    per m...
Oracle Technology Network 
    PHP Developer Center
• Free
• Articles
• Install guides
• Underground PHP 
  and Oracle Man...
Oracle Resources

• Free Oracle Techology Network (OTN)
  PHP Developer Center 
  • Underground PH...
Q & A
     Thank You

Upcoming SlideShare
Loading in …5



Published on

Published in: Technology
  • Be the first to comment

No Downloads
Total views
On SlideShare
From Embeds
Number of Embeds
Embeds 0
No embeds

No notes for slide


  1. 1. Solving the C20K Problem:  PHP Performance and Scalability Kuassi Mensah, Group Product Manager  Oracle Corporation
  2. 2. The C20K Problem 
  3. 3. Genesis: the C10K Problem • Circa 2003: “How to write a server which can handle  10.000 parallel connections” •
  4. 4. The C20K Problem • Can a single commodity database server handle 20K  simultaneous PHP users?  …
  5. 5. Solving C20K with Built­In Database   Mechanisms in PHP • Database Resident Connection Pool • Query Change Notification • Client­side Query Result Cache • Scaling with Stored Procedures • Database Built­in Partitioning • Scaling Very Complex Queries • Scaling Queries with Advanced Data Compression • Database Failover • Case Study: Community Connect
  6. 6. <Insert Picture Here> Database Resident  Connection Pool
  7. 7. PHP Lacks Proper Connection Pool Current choices:  2. Persistent Connections • Connection not automatically closed at                               script  completion • Fast for subsequent connections but         holds resources when application idle  ⇒ Over­allocation – Waste of system resources • Non Persistent Connections • Connection closed at script completion ⇒ High connect times                                                  ⇒ Unnecessary connect/disconnect CPU load
  8. 8. Database Resident Connection Pool   Dedicated servers Connection  Connection  Broker ( DB handle) Session Session Session (User Handle) Session 1 (User Handle) Session (User Handle) (User Handle) (User Handle) Oracle Net 2 • Pool of dedicated servers • (1) Server allocated/locked on  Appl. Connect  • (2) Direct server access after handoff • (3) Server released on Appl. ConnClose . • No man­in­the­middle, low latency
  9. 9. Database Resident Connection Pool • Pools a set of dedicated servers on each database   instance  • Designed primarily for  process systems (PHP)    1/ Just Change the Connect String  <?php $c = oci_pconnect(quot;phpwebquot;, quot;phpwebquot;, quot;//localhost/orcl:pooledquot;); $s = oci_parse($c, 'select * from employees'); oci_execute($s); oci_fetch_all($s, $res); var_dump($res); ?>     2/ Zero code change: change TNS alias • Currently in OCI, C/C++, PHP (OCI8), Python
  10. 10. DRCP in Action – PHP Connection Pooled Database  Servers 3 Busy Server Idle Server PHP PGA memory Session memory oci _ pco n nec t() 35k Idle Server 1 2 Apache Processes . . 35k . ) ct( ne on c Connection i_p oc PHP Broker
  11. 11. DRCP in Action – Closing Connection Pooled Database  Servers oci_close() Busy Server PHP PGA memory Connection Session memory Broker Idle Server 35k 4 Apache Processes . . PHP 35k . oci_close() 
  12. 12. DRCP in Action – After Close Pooled Database  Servers Idle Server PHP PGA memory Connection Session memory socket  Broker connection  Idle Server 35k 5 Apache Processes . . PHP 35k . socket  connection 
  13. 13. Configuring and Starting DRCP  • Configure the Pool (Optional)        SQL> execute dbms_connection_pool.configure_pool(pool_name                     =>       'SYS_DEFAULT_CONNECTION_POOL',       minsize    => 4,    maxsize        => 40,    incrsize      => 2,    session_cached_cursors   => 20,    inactivity_timeout         => 300,    max_think_time        => 600,    max_use_session           => 500000,   max_lifetime_session    => 86400); • Start the pool SQL> execute dbms_connection_pool.start_pool(); 
  14. 14. C20K, Yes We Did! PHP DRCP Benchmark • PHP script • connect, query, disconnect, sleep 1 second • Database Server • Dual CPU Intel P4/Xeon ­­ 3.00GHz ­ 2GB RAM • 32bit Red Hat Enterprise Linux 4 • DRCP • 100 pooled servers, one connection broker • 0.5% nb users simultaneously active  • PHP Hosts • 3  machines similar to Db Server • Apache • PHP DRCP Whitepaper:
  15. 15. C20K, Yes We Did! PHP DRCP Benchmark ­ Throughput
  16. 16. C20K, Yes We Did! PHP DRCP Benchmark ­ Memory
  17. 17. <Insert Picture Here> Query Change Notification
  18. 18. Built­in Query Change Notification  Problem to solve: Be notified when changes in the database invalidates  an existing query result set 2.Upon  Change  (DMLImpacting  <?php the result set) … Callout 4.Invalidate cache 5.repopulate cache … ?> 1. Register the query 3.Automatic  Custom cache    Notification    (Java or PL/SQL database job    as noificaion handler)
  19. 19. <Insert Picture Here> Client­Side Query Result Cache
  20. 20. MemCached  query = quot;select name, address, phone, acctbal from custumer, nation where c_nationkey= n_nationkey; key = md5($query); If (serval=$memcache->get($key) { res = oci_execute($query) Problems ser = serialize($res); memcache->set($key, $ser); • Cache Invalidation } • Additional  res = unserialize($serval);   Memcached Servers MemCached PHP Database
  21. 21. Built­in Client Query Result Cache   $query = quot;select /*+ RESULT_CACHE */ name, address, phone, acctbal from customer, nation where c_nationkey=n_nationkey; PHP Database • May be Faster than Memcached ! • No additional cache server(s)  but process level cache • Automatic Cache Invalidation  • Transparent OCI, PHP, Ruby, ODP.Net, ODBC, JDBC 
  22. 22. Configuring Client Query Result Cache  1/ Configure the Cache     Database Server Configuration (init.ora) client_result_cache_size=200M client_result_cache_lag=5000        Client Configuration (sqlnet.ora)  OCI_QUERY_CACHE_SIZE=200M OCI_QUERY_CACHE_MAXROWS=20 2/ Caching the Result Set Using Hints select /*+ result_cache */ * from employees        Alternatively, at Table level    alter table emp result_cache (mode force);
  23. 23. Client Query Result Cache 5­8 x Faster 900% 800% 700% 600% 500% 400% 300% 200% 100% 0% 10 100 1000
  24. 24. <Insert Picture Here> Scaling with Stored Procedures
  25. 25. Stored Procedures instead of Multiple  Unique Statements Stored Procedures (PL/SQL or Java) Unique Statements PHP PHP Stored Procedure Call Calls Java JDBC Calls SQL SQL Faster, up to 10X! 
  26. 26. PHP Bulk Insert   function do_transactional_insert($conn, $array) { $s = oci_parse($conn, 'insert into ptab (pdata) values (:bv)'); oci_bind_by_name($s, ':bv', $v, 20, SQLT_CHR); foreach ($array as $v) $r = oci_execute($s, OCI_DEFAULT); oci_commit($con); } Elapsed time: 8 millisec 
  27. 27. PHP Bulk Insert with Stored Procedure function do_bulk_insert($conn, $array) { $s = oci_parse($conn, 'begin mypkg.myproc(:c1); end;'); oci_bind_array_by_name($s, quot;:c1quot;, $array, count($array), -1, SQLT_CHR); oci_execute($s); } Elapsed time: 2 millisec (4X speed up; may vary!)   
  28. 28. PL/SQL Stored Proc. (Bulk insert) create or replace package mypkg as type arrtype is table of varchar2(20) index by pls_integer; procedure myproc(p1 in arrtype); end mypkg; create or replace package body mypkg as procedure myproc(p1 in arrtype) is begin forall i in indices of p1 insert into ptab values (p1(i)); end myproc; end mypkg;
  29. 29. Using Java Stored Procedures in PHP  • Secure Credit­Card Processing  • Implement Parsers for various File  using JSSE Formats (txt, zip, xml, binary) • Custom Alert applications that  • Implement Image Transformation and  monitor business data Format Conversion (GIF, PNG,  • Sending emails with attachment  JPEG, etc) from within the database • Implement database­resident Content  • Produce PDF files from Result  Management System Set • HTTP Call­Out • Execute external OS commands  • JDBC Call­Out and external procedures • Implement Md5 CRC • RMI Call­Out to SAP • Publish Repository Content to  • Web Services Call­Out Portal • Messaging across Tiers • Portable Logistic Applications • RESTful Database Web Services* • Db Resident Lucene* *
  30. 30. <Insert Picture Here> Database Built­in Partitioning
  31. 31. Built­in Partitioning  Orders Line Inventory Items Orders Jan Orders Feb Back  Pick Orders Orders Lists Mar
  32. 32. <Insert Picture Here> Scaling Very Complex SQL  Queries 
  33. 33. Scaling Very Complex SQL Queries  Problem to Solve: Query Sales and Quantity by Year, Department, Class and Country The SQL Query  SELECT SUM(s.quantity) AS quantity, SUM(s.sales) AS sales, t.calendar_year_name, p.department_name, c.class_name, cu.country_name FROM times t, products p, channels c, customers cu, sales_fact s WHERE p.item_key = s.product AND s.day_key = t.day_key AND = c.channel_key AND s.customer = cu.customer_key GROUP BY p.department_name, t.calendar_year_name, c.class_name, cu.country_name;
  34. 34. Built­in OLAP Engine PHP
  35. 35. Cube Organized Materialized Views Transparent to SQL Queries Materialized Views SQL Query Region Date Query Rewrite Product Channel Automatic OLAP Cube Refresh
  36. 36. <Insert Picture Here> Scaling with Advanced Data  Compression
  37. 37. Scaling w. Advanced Data Compression  Going Green  Storage  2500 Reduction More than 70% (up to 4X)  2000 Compression Storage Savings 1500 MB No Compression 1000 500 0 Table Scan Performance DML Performance Less than  3% Overhead 0.4 40 2.5 x Faster 0.3 (seconds) 30 (seconds) Time  Time  0.2 20 0.1 10 0 0
  38. 38. Database Failover
  39. 39. Oracle Database 11g RAC  Shared Disk Architecture
  40. 40. Fast Application Notification of Events • Pub/Sub Event Notification (AQ based) • High Availability feature for PHP with RAC or Data­  Guard­with­physical­standby • When DB node or network fails • Database generates FAN events • PHP error returned without TCP timeout delay • PHP application reconnect to surviving instance • OCI8 1.3.1 Beta supports FAN
  41. 41. Database Failover – Application View Fast Connection Failover Invalid Connections Valid Connections Inst x Inst y
  42. 42. Configuring Fast Application  Notification for PHP • High Availability feature with RAC or DG • Usable with or without DRCP • Available from Oracle 10gR2 • OCI8 1.3 supports FAN  5.Tell DB to broadcast FAN Events SQL> execute      dbms_service.modify_service(service_name =>'SALES',  aq_ha_notifications =>TRUE);  6.Subscribe to FAN events  Example: Configure PHP for OCI8 to listen for FAN events = On 7.Application to Re­connect
  43. 43. Database Failover in PHP  When DB node or network fails • Database generates FAN events • Oracle error returned without TCP timeout delay • PHP application is not blocked for TCP timeout – it can  immediately reconnect to surviving DB instance $conn = doConnect(); $err = doSomeWork($conn); if (isConnectionError($err)) {   // reconnect, find what was committed, and retry   $conn = doConnect();   $err = checkApplicationStateAndContinueWork($conn); } if ($err)    handleError($err);
  44. 44. C(N*20)K Using DRCP and RAC • Scale your database horizontally to N*C20K with N  RAC nodes!! • DRCP starts on all RAC instances • Same pool limits apply to each individual RAC  instance • min, max • number of brokers • max connections per broker • DRCP connections benefit from TNS Listener  connection load balancing across RAC instances­scalability­ha­twp.pdf
  45. 45. <Insert Picture Here> Case Study  Community Connect Inc.  
  46. 46. Xtreme Scalability Web Scale PHP Deployment  • 19+ million users • 500+ millions pages views     per month  • 100+ web servers • 10+ databases (incl. RAC) • ~ 50,000 conc. Users • Case Studied by Gartner
  47. 47. Oracle Technology Network  PHP Developer Center • Free • Articles • Install guides • Underground PHP  and Oracle Manual  • Online forum • PHP RPMs • Oracle JDeveloper  10g PHP extension 
  48. 48. Oracle Resources • Free Oracle Techology Network (OTN) PHP Developer Center  • Underground PHP and Oracle Manual • Whitepapers, Articles, FAQs, links to blogs, JDeveloper  PHP Extension, PHP RPMs • Information • SQL and PL/SQL Questions • ISVs and hardware vendors
  49. 49. Q & A Thank You 49