Symfony2 + Doctrine 
PostgreSQL 
Symfony2 ve Doctrine ile PostgreSQL'i 
kullanarak Performanslı Mimari oluşturma 
1
çok sevdiğimiz diller 
2
çok sevdiğimiz veribanları 
3
çok sevdiğimiz ortamlar 
4
yapan kraldır 
5 @okulbilisim
Ajanda 
● Performans nedir? 
● Performans analizi nasıl yapılır? 
● Nginx ve FPM performans 
● Symfony2 performans 
● Doctrine performans 
● Web Sayfasındaki performans 
● Organik DDoS (Normal insan saldırısı) 
6
Performans? 
facebook gibi hızlı geliyor 
7
her şeyi cachelemek, arkada yapıp getirmek iyidir 
8
keşler 
LB cache 
Nginx FastCGI 
app/cache and APC 
Response caching & HTTP-CACHE 
Doctrine2 Query & Result Caching 
CDN 
9
http://analytics.blogspot.com.tr/2012/04/global-site-speed-overview-how-fast-are.html 
10
Performans analizi nasıl 
yapılır? 
load test 
11
https://twitter.com/yuxel/status/279319192757493760 
12 
@GoyGoyTR
Load Test 
http://jmeter.apache.org/ 
13
Araçlar 
● htop 
● siege 
● hping3 
● dstat 
● wacth -n .5 ‘netstat -ant|grep ESTAB|wc -l’ 
● iostat 
● çok bilgi 
14
nginx + fpm 
apache? 
15
nginx + fpm 
16 
1. SSD 
2. TCP -> UNIX domain sockets. 
3. worker_processes 
4. worker_connections. 
5. upstream 
6. access_log off; 
7. GZip. 
8. fast_cgi_cache 
9. client timeouts. 
10. output buffers. 
11. /etc/sysctl.conf 
http://highscalability.com/blog/2014/4/30/10-tips-for-optimizing-nginx-and-php-fpm-for-high-traffic-si.html 
http://lukasz.cepowski.com/devlog/43,high-performance-web-server-with-nginx-and-php-fpm 
http://blog.martinfjordvald.com/2010/09/12000-requests-per-second-with-nginx-php-and-memcached/
gc_disable 
17 
https://github.com/composer/composer/commit/ac676f47f7bbc619678a29deae097b6b0710b799 
http://blog.ircmaxell.com/2014/12/what-about-garbage.html
Symfony2 Performans 
18
19 
Symfony zaten hızlı 
Daha hızlı olması için yapabileceğiniz çok 
az şey var.
Byte Code Cache 
Apc 
Xcache 
ionCube 
Zend Opcache 
20
Composer Class Map 
composer dump-autoload --optimize 
21
Dump Router 
php app/console --env=prod router:dump 
... 
RewriteCond %{REQUEST_URI} ^/city$ 
RewriteRule .* $0/ [QSA,L,R=301] 
RewriteCond %{REQUEST_URI} ^/city/$ 
RewriteRule .* app.php 
[QSA,L,E=_ROUTING_route:city,E=_ROUTING_default__controller:TestBundleControllerCityController::ind 
exAction] 
... 
22
Doctrine 
23
Doctrine 
The Doctrine Project is the home to several 
PHP libraries primarily focused on database 
storage and object mapping. The core projects 
are a Object Relational Mapper (ORM) and 
the Database Abstraction Layer (DBAL) it is 
built upon. 
http://www.doctrine-project.org/ 
24
doctrine: 
orm: 
metadata_cache_driver: memcache 
query_cache_driver: memcache 
result_cache_driver: memcache 
25
Memcache 
APC 
Redis 
Xcache 
File 
Custom Cache Service 
26
Metadata Cache 
Her istek sırasında Annotation, YAML, XML gibi 
farklı bir çok yerden class metadata 
oluşturulmasının önüne geçer 
27
Query Cache 
DQL sorgusunun SQL karşılığının bir değişim 
olmadığı sürece tekrar tekrar 
oluşturulmasından kaynaklı performans kaybını 
gidermek için 
28
Result Cache 
Sadece ihtiyaç halinde 
$query = $em->createQuery('...'); 
$query->useResultCache(true); 
// setResultCacheLifetime(3600); 
// setResultCacheId('my_custom_id'); 
// useResultCache(true, 3600, 'my_custom_id'); 
29
30 
Cache Slam!
Fetch Modes 
31
Lazy vs Extra Lazy 
Doctrine 2.0 Doctrine 2.1 
32
getSinlgeScalarResult 
$ref = $em->createQuery( "SELECT PARTIAL s.title " . 
"FROM BlogBundle:Post s " . 
"WHERE s.id = ?1" )->setParameter(1, $id) 
->getSingleScalerResult() 
33
getPartialReference 
$ref = $em->createQuery( "SELECT PARTIAL s.{keywords,title} " . 
"FROM BlogBundle:Post s " . 
"WHERE s.id = ?1" )->setParameter(1, $id)->getResult(); 
$ref = $em->getPartialReference("BlogBundle:Post", $id) 
34
Teşekkür Ederiz 
@hmert @htayyar 
@OkulBilisim 
info@okulbilisim.com 
35

Symfony2 ve Doctrine ile PostgreSQL'i Kullanarak Performanslı Mimari Oluşturma

Editor's Notes

  • #2 test
  • #19 http://symfony.com/doc/current/book/performance.html#use-a-byte-code-cache-e-g-apc
  • #22 autoload class dosyalarının filecheck ile path kontrollerinin önün geçer
  • #25 Object relational mapper (ORM) for PHP that sits on top of a powerful database abstraction layer (DBAL). One of its key features is the option to write database queries in a proprietary object oriented SQL dialect called Doctrine Query Language (DQL), inspired by Hibernates HQL. This provides developers with a powerful alternative to SQL that maintains flexibility without requiring unnecessary code duplication.
  • #31 Something to be careful of when using the cache drivers is “cache slams”. Imagine you have a heavily trafficked website with some code that checks for the existence of a cache record and if it does not exist it generates the information and saves it to the cache. Now, if 100 requests were issued all at the same time and each one sees the cache does not exist and they all try to insert the same cache entry it could lock up APC, Xcache, etc. and cause problems. Ways exist to work around this, like pre-populating your cache and not letting your users’ requests populate the cache.
  • #33 In many cases associations between entities can get pretty large. Even in a simple scenario like a blog. where posts can be commented, you always have to assume that a post draws hundreds of comments. In Doctrine 2.0 if you accessed an association it would always get loaded completely into memory. This can lead to pretty serious performance problems, if your associations contain several hundreds or thousands of entities. With Doctrine 2.1 a feature called Extra Lazy is introduced for associations. Associations are marked as Lazy by default, which means the whole collection object for an association is populated the first time its accessed. If you mark an association as extra lazy the following methods on collections can be called without triggering a full load of the collection: Collection#contains($entity) Collection#containsKey($key) (available with Doctrine 2.5) Collection#count() Collection#get($key) (available with Doctrine 2.4) Collection#slice($offset, $length = null)
  • #35 Another interesting use-case: updating an object without loading it (as an alternative to a DQL bulk UPDATE): $user = $em->getPartialReference('User', $userId); $user->setName('newname'); $em->flush();