caddyserver / caddy

Fast and extensible multi-platform HTTP/1-2-3 web server with automatic HTTPS
https://caddyserver.com
Apache License 2.0
57.66k stars 4.01k forks source link

Caching options available to Caddy ? #390

Closed centminmod closed 8 years ago

centminmod commented 8 years ago

Hi guys nice project you have going, Caddy was certainly easy to install and get up and running for testing. But curious in the context of comparisons to Nginx, what available cache options are available to Caddy ?

For example nginx has

So do Caddy equivalents exist ?

mholt commented 8 years ago

Not yet - but it's been on the todo list for a while, see #10 (and somewhat related, #191)

Turns out it's really hard to do just right. I wonder if this would make a better add-on than in core. But either way, I think it would be great.

centminmod commented 8 years ago

cheers @mholt is there a keep alive option ?

mholt commented 8 years ago

Yeah, it's currently set at 3 minutes. Will probably make that configurable later.

centminmod commented 8 years ago

I see.. thanks @mholt :)

I ask as I decided to play with Caddy on port 81 local virtualbox CentOS 7.1 guest OS server which already has another Nginx server running on port 80 via CentminMod.com LEMP stack. Using a local PC and server hosts file edit to map domain1.com to virtualbox server Ip and I think maybe the difference is Siege benchmark tests is nginx keep alives or the differences in available cache options ?

/opt/caddy/Caddyfile

domain1.com:81
gzip
browse
tls off
root /usr/local/nginx/html
log /opt/caddy/access.log

launching caddy

caddy --conf=/opt/caddy/Caddyfile -pidfile=/var/run/caddy.pid

versions

caddy -version
 Caddy 0.8    

nginx -V
nginx version: nginx/1.9.7
built by clang 3.4.2 (tags/RELEASE_34/dot2-final)
built with LibreSSL 2.2.4
TLS SNI support enabled
configure arguments: --with-ld-opt='-lrt -ljemalloc -Wl,-z,relro -Wl,-rpath,/usr/local/lib' --with-cc-opt='-m64 -mtune=native -g -O2 -fstack-protector --param=ssp-buffer-size=4 -Wformat -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -Wno-string-plus-int -Wno-deprecated-declarations -Wno-unused-parameter -Wno-unused-const-variable -Wno-conditional-uninitialized -Wno-mismatched-tags -Wno-c++11-extensions -Wno-sometimes-uninitialized -Wno-parentheses-equality -Wno-tautological-compare -Wno-self-assign -Wno-deprecated-register -Wno-deprecated -Wno-invalid-source-encoding -Wno-pointer-sign -Wno-parentheses -Wno-enum-conversion' --sbin-path=/usr/local/sbin/nginx --conf-path=/usr/local/nginx/conf/nginx.conf --with-http_stub_status_module --with-http_secure_link_module --with-openssl-opt=enable-tlsext --add-module=../nginx-module-vts --with-libatomic --with-threads --with-stream --with-stream_ssl_module --with-http_gzip_static_module --add-module=../ngx_pagespeed-1.9.32.10-beta --with-http_sub_module --with-http_addition_module --with-http_image_filter_module --with-http_geoip_module --with-http_realip_module --add-module=../nginx-accesskey-2.0.3 --add-module=../nginx-http-concat-master --add-module=../ngx-fancyindex-ngx-fancyindex --add-module=../ngx_cache_purge-2.3 --add-module=../ngx_devel_kit-0.2.19 --add-module=../set-misc-nginx-module-0.29 --add-module=../echo-nginx-module-0.58 --add-module=../redis2-nginx-module-0.12 --add-module=../ngx_http_redis-0.3.7 --add-module=../lua-nginx-module-0.9.18 --add-module=../lua-upstream-nginx-module-0.04 --add-module=../lua-upstream-cache-nginx-module-0.1.1 --add-module=../nginx_upstream_check_module-0.3.0 --add-module=../openresty-memc-nginx-module-4f6f78f --add-module=../openresty-srcache-nginx-module-ffa9ab7 --add-module=../headers-more-nginx-module-0.28 --with-pcre=../pcre-8.37 --with-pcre-jit --with-http_ssl_module --with-http_v2_module --with-openssl=../libressl-2.2.4

headers

curl -I http://domain1.com:81/
HTTP/1.1 200 OK
Accept-Ranges: bytes
Content-Length: 3801
Content-Type: text/html; charset=utf-8
Last-Modified: Sat, 28 Nov 2015 11:55:01 GMT
Server: Caddy
Date: Sat, 05 Dec 2015 20:16:31 GMT

compare to centminmod.com nginx server on port 80

curl -I http://domain1.com:80
HTTP/1.1 200 OK
Date: Sat, 05 Dec 2015 20:24:11 GMT
Content-Type: text/html; charset=utf-8
Content-Length: 3801
Last-Modified: Sat, 28 Nov 2015 11:55:01 GMT
Connection: keep-alive
Vary: Accept-Encoding
ETag: "56599615-ed9"
Server: nginx centminmod
Cache-Control: public, must-revalidate, proxy-revalidate
Accept-Ranges: bytes

siege bench caddy vs centminmod nginx plain HTTP/1.1 non-HTTPS test

siege --version
SIEGE 3.1.3    

caddy

siege -q -b -c25 -r30 http://domain1.com:81
      done.

Transactions:                    750 hits
Availability:                 100.00 %
Elapsed time:                   0.47 secs
Data transferred:               1.13 MB
Response time:                  0.02 secs
Transaction rate:            1595.74 trans/sec
Throughput:                     2.41 MB/sec
Concurrency:                   24.09
Successful transactions:         750
Failed transactions:               0
Longest transaction:            0.05
Shortest transaction:           0.00

nginx - only 2 out of 4 cpu cores allocated to nginx

siege -q -b -c25 -r30 http://domain1.com:80
      done.

Transactions:                    750 hits
Availability:                 100.00 %
Elapsed time:                   0.13 secs
Data transferred:               1.13 MB
Response time:                  0.00 secs
Transaction rate:            5769.23 trans/sec
Throughput:                     8.69 MB/sec
Concurrency:                   21.77
Successful transactions:         750
Failed transactions:               0
Longest transaction:            0.05
Shortest transaction:           0.00

virtualbox guest CentOS 7.1 OS specs

On Samsung laptop with Core i7 3635QM with 2GB ram allocated and 4 cpu threads

cat /proc/cpuinfo
processor       : 0
vendor_id       : GenuineIntel
cpu family      : 6
model           : 58
model name      : Intel(R) Core(TM) i7-3635QM CPU @ 2.40GHz
stepping        : 9
microcode       : 0x19
cpu MHz         : 2394.681
cache size      : 6144 KB
physical id     : 0
siblings        : 4
core id         : 0
cpu cores       : 4
apicid          : 0
initial apicid  : 0
fpu             : yes
fpu_exception   : yes
cpuid level     : 5
wp              : yes
flags           : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 ht syscall nx rdtscp lm constant_tsc rep_good nopl pni ssse3 lahf_lm
bogomips        : 4789.36
clflush size    : 64
cache_alignment : 64
address sizes   : 36 bits physical, 48 bits virtual
power management:

processor       : 1
vendor_id       : GenuineIntel
cpu family      : 6
model           : 58
model name      : Intel(R) Core(TM) i7-3635QM CPU @ 2.40GHz
stepping        : 9
microcode       : 0x19
cpu MHz         : 2394.681
cache size      : 6144 KB
physical id     : 0
siblings        : 4
core id         : 1
cpu cores       : 4
apicid          : 1
initial apicid  : 1
fpu             : yes
fpu_exception   : yes
cpuid level     : 5
wp              : yes
flags           : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 ht syscall nx rdtscp lm constant_tsc rep_good nopl pni ssse3 lahf_lm
bogomips        : 4789.36
clflush size    : 64
cache_alignment : 64
address sizes   : 36 bits physical, 48 bits virtual
power management:

processor       : 2
vendor_id       : GenuineIntel
cpu family      : 6
model           : 58
model name      : Intel(R) Core(TM) i7-3635QM CPU @ 2.40GHz
stepping        : 9
microcode       : 0x19
cpu MHz         : 2394.681
cache size      : 6144 KB
physical id     : 0
siblings        : 4
core id         : 2
cpu cores       : 4
apicid          : 2
initial apicid  : 2
fpu             : yes
fpu_exception   : yes
cpuid level     : 5
wp              : yes
flags           : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 ht syscall nx rdtscp lm constant_tsc rep_good nopl pni ssse3 lahf_lm
bogomips        : 4789.36
clflush size    : 64
cache_alignment : 64
address sizes   : 36 bits physical, 48 bits virtual
power management:

processor       : 3
vendor_id       : GenuineIntel
cpu family      : 6
model           : 58
model name      : Intel(R) Core(TM) i7-3635QM CPU @ 2.40GHz
stepping        : 9
microcode       : 0x19
cpu MHz         : 2394.681
cache size      : 6144 KB
physical id     : 0
siblings        : 4
core id         : 3
cpu cores       : 4
apicid          : 3
initial apicid  : 3
fpu             : yes
fpu_exception   : yes
cpuid level     : 5
wp              : yes
flags           : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 ht syscall nx rdtscp lm constant_tsc rep_good nopl pni ssse3 lahf_lm
bogomips        : 4789.36
clflush size    : 64
cache_alignment : 64
address sizes   : 36 bits physical, 48 bits virtual
power management:
mholt commented 8 years ago

What's your nginx.conf for those benchmarks?

centminmod commented 8 years ago

nginx.conf is same as https://github.com/centminmod/centminmod/blob/123.09beta01/config/nginx/nginx.conf just worker_processes 2

i suspect it's related to open_file_cache and/or keep-alives ?

okay scratch that siege not using keep alive by default

# 
# Cache revalidation.
# Siege supports cache revalidation for both ETag and 
# Last-modified headers. If a copy is still fresh, the 
# server responds with 304. 
# HTTP/1.1 200   0.00 secs:    2326 bytes ==> /apache_pb.gif
# HTTP/1.1 304   0.00 secs:       0 bytes ==> /apache_pb.gif
# HTTP/1.1 304   0.00 secs:       0 bytes ==> /apache_pb.gif
# 
# ex: cache = true
#
cache = false

#
# Connection directive. Options "close" and "keep-alive"
# Starting with release 2.57b3, siege implements persistent 
# connections in accordance to RFC 2068 using both chunked
# encoding and content-length directives to determine the 
# page size. To run siege with persistent connections set
# the connection directive to keep-alive. (Default close)
# CAUTION: use the keep-alive directive with care.
# DOUBLE CAUTION: this directive does not work well on HPUX
# TRIPLE CAUTION: don't use keep-alives until further notice
# ex: connection = close
#     connection = keep-alive
#
connection = close    
centminmod commented 8 years ago

with nginx open_file_cache and open_log_file_cache disabled

siege -q -b -c25 -r30 http://domain1.com:80
      done.

Transactions:                    750 hits
Availability:                 100.00 %
Elapsed time:                   0.16 secs
Data transferred:               1.13 MB
Response time:                  0.00 secs
Transaction rate:            4687.50 trans/sec
Throughput:                     7.06 MB/sec
Concurrency:                   20.75
Successful transactions:         750
Failed transactions:               0
Longest transaction:            0.05
Shortest transaction:           0.00    
centminmod commented 8 years ago

or related to https://github.com/mholt/caddy/issues/10#issuecomment-156913216

There is certainly a need for caching to scale Caddy. The profiling shows that the performance is hindered by File I/O being made for every request.Will soon release documents and reviews on performance and enhancement suggestion for each middleware from the profiling and performance tests I'm doing. I'm also looking at Groupcache and checking out whether it could be integrated for caching static contents

centminmod commented 8 years ago

caddy phpinfo file test (file and php-fpm was already installed via centminmod.com LEMP installer so just had to pass it to Caddyfile)

curl -I http://domain1.com:81/11642b2c_phpi.php
HTTP/1.1 200 OK
Content-Type: text/html
Server: Caddy
Date: Sat, 05 Dec 2015 23:15:10 GMT

siege -q -b -c25 -r30 http://domain1.com:81/11642b2c_phpi.php
      done.

Transactions:                    750 hits
Availability:                 100.00 %
Elapsed time:                   2.69 secs
Data transferred:              15.47 MB
Response time:                  0.09 secs
Transaction rate:             278.81 trans/sec
Throughput:                     5.75 MB/sec
Concurrency:                   24.22
Successful transactions:         750
Failed transactions:               0
Longest transaction:            0.37
Shortest transaction:           0.01

nginx with same php-fpm server

curl -I http://domain1.com:80/11642b2c_phpi.php
HTTP/1.1 200 OK
Date: Sat, 05 Dec 2015 23:15:03 GMT
Content-Type: text/html; charset=utf-8
Connection: keep-alive
Vary: Accept-Encoding
Server: nginx centminmod

siege -q -b -c25 -r30 http://domain1.com:80/11642b2c_phpi.php
      done.

Transactions:                    750 hits
Availability:                 100.00 %
Elapsed time:                   1.42 secs
Data transferred:              15.79 MB
Response time:                  0.04 secs
Transaction rate:             528.17 trans/sec
Throughput:                    11.12 MB/sec
Concurrency:                   23.49
Successful transactions:         750
Failed transactions:               0
Longest transaction:            0.42
Shortest transaction:           0.01

config used for /opt/caddy/Caddyfile

domain1.com:81
gzip {
        level 6
}
browse
tls off
root /usr/local/nginx/html

fastcgi / 127.0.0.1:9000 {
        ext   .php
        split .php
        index index.php
}

log /opt/caddy/access.log {
        rotate {
                size 100 # Rotate after 100 MB
                age  14  # Keep log files for 14 days
                keep 10  # Keep at most 10 log files
        }
}

command to run Caddy

 caddy --conf=/opt/caddy/Caddyfile -pidfile=/var/run/caddy.pid

default out of box PHP version for 123.09beta01 CentminMod LEMP's php-fpm is 5.5.30

php -v
PHP 5.5.30 (cli) (built: Nov 28 2015 12:01:26) 
Copyright (c) 1997-2015 The PHP Group
Zend Engine v2.5.0, Copyright (c) 1998-2015 Zend Technologies
    with Zend OPcache v7.0.6-dev, Copyright (c) 1999-2015, by Zend Technologies

php modules loaded

php -m
[PHP Modules]
bcmath
bz2
calendar
Core
ctype
curl
date
dom
enchant
ereg
exif
filter
ftp
gd
geoip
gettext
gmp
hash
iconv
igbinary
imagick
imap
intl
json
libxml
mbstring
mcrypt
memcache
memcached
mhash
mongo
mysql
mysqli
mysqlnd
openssl
pcntl
pcre
PDO
pdo_mysql
pdo_sqlite
Phar
posix
pspell
readline
redis
Reflection
session
shmop
SimpleXML
snmp
soap
sockets
SPL
sqlite3
standard
sysvmsg
sysvsem
sysvshm
tidy
tokenizer
xml
xmlreader
xmlrpc
xmlwriter
Zend OPcache
zip
zlib

[Zend Modules]
Zend OPcache        
pwFoo commented 8 years ago

Caching would be great and could push the caddy webserver.

Would it be difficult to create a cache extension to write static files to a configured directory? 1) Load cached file if exists 2) exclude extension, directories or files 3) remove single page from cache (via a api / web request like varnish proxy

Zizaco commented 8 years ago

@pwFoo That would be great! :+1:

pwFoo commented 8 years ago

Maybe simple caching could be done with a rewrite (load file if exists, else...)? https://github.com/mholt/caddy/pull/463#issuecomment-167891453

rewrite {
    to {uri} {uri}/ /the_new_url
}

Caching would be great, but need the chance to delete cached pages by a request like possible with Varnish.

mholt commented 8 years ago

Anyone want to take ownership of this issue? Feel free to claim it -- it'd be all yours.

mholt commented 8 years ago

There is some work started on this; chime in on gitter if you're interested in knowing more.

GeertJohan commented 8 years ago

Is this ossue still valid for 0.9?

mholt commented 8 years ago

Meh, kind of. The more I look at this issue though, the more I realize it's not specific enough to be actionable. "Caching" is a very, very broad term. And I don't even know exactly what kind of caching we're talking about toward the end here. Or what kind of specific problem we're trying to solve. I'm going to close this in favor of more specific issues with a real-life problem and a proposal for a real-world solution.

faddat commented 8 years ago

@mholt

Trying to figure out a real-world solution, so I'll toss you my scenario: 30 wordpress instances running on a scaleway node X 20, with a 21st node running caddy. Curious community's thoughts on a good approach to caching in this situation.

nahidakbar commented 7 years ago

@mholt It is kind of sad that this is closed.

For caching, as I see it can serve two functions:

First, it helps boost performance of weaker servers. We are forced to still use a few java based solutions which are extremely slow. Putting a cache in front of them speeds things up. I am guessing a lot of people who still use older generation technology like php will find this helpful.

Second, performance! With the way I design things, over 90% of the requests end up being read only. These don't need to be processed or served by a back end more than once. Even with that not being the case, every time one of these assets are needed, caddy needs to go back to the back end, get the response and forward it back. That is time and resources that does not need to be wasted.

In addition, I think caddy is in an unique position to exploit the benefits of caching much better than other servers. It supports all the faster more concurrent transmission protocols. If it has the data cached, it can serve them faster than static files.

But yeah, I would strongly recommend not going down the path of memcached like nginx did. Horrible horrible model of caching. If you are gonna implement caching, objective of which is to improve performance, best solution IMO is having the ability to allocate a certain size memory to it inside caddy itself.

mholt commented 7 years ago

@nahidakbar This isn't closed because it won't happen, it's just that there's nothing specific enough to act on here. Proposals need to be very specific, implementable, technical; not just describing related use cases where caching would be helpful.