Make DynamoDB table
Table Name: ProductCatalog
Primary Hash Key: Id (String)
Provisioned Read Capacity Units: 10000
Provisioned Write Capacity Units: 10000
Region: Asia Pacific (Tokyo)
Launch EC2 Instance
AMI ID: Amazon Linux AMI 2015.09 (HVM), SSD Volume Type - ami-9a2fb89a
Instance type: c4.xlarge
Install PHP and AWS SDK for PHP
Install PHP5.6
# yum -y install php56 php56-devel php56-fpm php56-opcache gccMake app dir and install new version of aws-sdk-php by Composer.
# mkdir ~/sample_app; cd ~/sample_app # curl -sS https://getcomposer.org/installer | php # php composer.phar require aws/aws-sdk-php # php composer.phar require doctrine/cache # php composer.phar install --optimize-autoloader # yum -y install php-pear # pecl install uri_template # echo "extension=uri_template.so" >> /etc/php.ini # php composer.phar show --installed | grep aws/aws-sdk-php aws/aws-sdk-php 3.9.1 AWS SDK for PHP - Use Amazon Web Services in your PHP projectMake AWS credentials file.
# mkdir ~/.aws/ # emacs ~/.aws/credentials [default] aws_access_key_id = YOUR_AWS_ACCESS_KEY_ID aws_secret_access_key = YOUR_AWS_SECRET_ACCESS_KEYMake sample put app
# emacs put.php <?php require 'vendor/autoload.php'; use Aws\DynamoDb\DynamoDbClient; $client = DynamoDbClient::factory(array( 'profile' => 'default', 'region' => 'ap-northeast-1', 'version' => '2012-08-10', 'credentials.cache' => true, 'validation' => false, 'scheme' => 'http' )); $response = $client->putItem(array( 'TableName' => 'ProductCatalog', 'Item' => array( 'Id' => array('S' => '104' ), // Primary Key 'Title' => array('S' => 'Book 104 Title' ), 'ISBN' => array('S' => '111-1111111111' ), 'Price' => array('N' => '25' ), 'Authors' => array('SS' => array('Author1', 'Author2') ) ) ));Run.
# php put.php
Make sample get app
# emacs get.php <?php require 'vendor/autoload.php'; use Aws\DynamoDb\DynamoDbClient; $client = DynamoDbClient::factory(array( 'profile' => 'default', 'region' => 'ap-northeast-1', 'version' => '2012-08-10', 'credentials.cache' => true, 'validation' => false, 'scheme' => 'http' )); $response = $client->getItem(array( 'TableName' => 'ProductCatalog', 'Key' => array( 'Id' => array( 'S' => '104' ) ) )); print_r ($response['Item']);Run
# php get.php Array ( [ISBN] => Array ( [S] => 111-1111111111 ) [Id] => Array ( [S] => 104 ) [Authors] => Array ( [SS] => Array ( [0] => Author1 [1] => Author2 ) ) [Price] => Array ( [N] => 25 ) [Title] => Array ( [S] => Book 104 Title ) )
Benchmark
Setup Nginx.
# yum -y install nginx # mkdir /var/lib/nginx/.aws/ # cp ~/.aws/credentials /var/lib/nginx/.aws/credentials # cp -r ~/sample_app/* /usr/share/nginx/html/ # emacs /etc/php-fpm.d/www.conf user = apache group = apache -> user = nginx group = nginx # emacs /etc/nginx/nginx.conf server { include /etc/nginx/default.d/*.conf; # /etc/init.d/nginx start # /etc/init.d/php-fpm start # curl 127.0.0.1/get.php -vRun benchmark.
# ab -c 100 -n 10000 http://127.0.0.1/put.php Requests per second: 763.44 [#/sec] (mean) # ab -c 100 -n 10000 http://127.0.0.1/get.php Requests per second: 832.62 [#/sec] (mean)Maybe. If I install AWS SDK with ClassPreloader, that will be more faster.
But, ClassPreloader does not work with AWS SDK for PHP version 3.
Please let me know, if you know how to use ClassPreloader.
Next section. I tried a other way.
Benchmark with Go DynamoDB Proxy
Use bbpd.
http://takeshiyako.blogspot.jp/2015/10/go-lang-bbpd-godynamo-http-proxy.html
Make sample apps.
# emacs /usr/share/nginx/html/get_go.php <?php $url = "http://localhost:12333/GetItemJSON"; $postdata = "{\"Key\": {\"Id\": {\"S\": \"104\"}}, \"TableName\": \"ProductCatalog\"}"; $ch = curl_init($url); curl_setopt($ch, CURLOPT_POST, true); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_POSTFIELDS, $postdata); $result = curl_exec($ch); curl_close($ch); echo $result; # emacs /usr/share/nginx/html/put_go.php <?php $random = substr(str_shuffle('1234567890abcdefghijklmnopqrstuvwxyz'), 0, 36); $url = "http://localhost:12333/PutItemJSON"; $postdata = "{\"Item\": {\"Id\": \"$random\",\"Title\":\"Book 107 Title\",\"ISBN\":\"111-1111111111\",\"Price\":\"33\",\"Authors\":[\"Author1\", \"Author2\"]},\"TableName\": \"ProductCatalog\"}"; $ch = curl_init($url); curl_setopt($ch, CURLOPT_POST, true); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_POSTFIELDS, $postdata); $result = curl_exec($ch); curl_close($ch); echo $result;Run benchmark.
# ab -c 100 -n 10000 http://127.0.0.1/get_go.php Requests per second: 4260.64 [#/sec] (mean) # ab -c 100 -n 10000 http://127.0.0.1/put_go.php Requests per second: 3753.05 [#/sec] (mean)It seems this solution is better than AWS SDK for PHP.
NOTE: When update same Id, many RETRY occurs with authreq. result of benchmark is 750 req/s.
if you update many data, please carefully.
https://github.com/smugmug/godynamo/blob/master/authreq/authreq.go#L91
See also
AWS SDK for PHP 3.x
http://docs.aws.amazon.com/aws-sdk-php/v3/api/index.html
Requirements — AWS SDK for PHP documentation
http://docs.aws.amazon.com/aws-sdk-php/v3/guide/getting-started/requirements.html
Performance Guide — AWS SDK for PHP 2.8.22 documentation
http://docs.aws.amazon.com/aws-sdk-php/v2/guide/performance.html
Top image from Felix De Vliegher Enjoying the view