V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
Distributions
Ubuntu
Fedora
CentOS
中文资源站
网易开源镜像站
sajesemuy
V2EX  ›  Linux

推荐高性能缓存服务器 nuster

  •  
  •   sajesemuy ·
    jiangwenyuan · 2017-11-06 17:39:53 +08:00 · 2850 次点击
    这是一个创建于 2573 天前的主题,其中的信息可能已经有所发展或是发生改变。

    Nuster 是一个基于 HAProxy 的高性能缓存服务器

    https://github.com/jiangwenyuan/nuster

    介绍

    Nuster 是一个基于 HAProxy 的高性能缓存服务器。Nuster 完全兼容 HAProxy,并且利用 HAProxy 的 ACL 功能来提供非常细致的缓存规则,比如

    • 请求地址为某某时缓存
    • 请求参数中的 X 为 Y 时缓存
    • 响应头中的 X 为 Y 时缓存
    • 请求速率超过多少时缓存
    • 等等

    性能

    非常快, 单进程模式下是 nginx 的 3 倍,多进程下 nginx 的 2 倍,varnish 的 3 倍。

    详见benchmark

    安装

    make TARGET=linux2628
    make install
    

    具体参照HAProxy README

    使用方法

    global中添加cache on, 然后在backendlisten中添加 cache filter 和 cache rule

    指令

    cache

    syntax: cache on|off [data-size size]

    default: none

    context: global

    控制是否开启缓存。 可以设置data-size来控制缓存数据的内存使用量。可以使用m, M, gG. 默认是 1MB,同时也是最小使用量。只有 http 内容计算在内,并不包括使用缓存带来的内存开销。

    filter cache

    syntax: filter cache [on|off]

    default: on

    context: backend, listen

    定义一个 cache filter, 另外cache-rule也需要添加。 可以为多个代理添加,并单独设置某个代理的缓存是否开启。 如果定义了多个 filter,需要把 cache filter 放在最后。

    cache-rule

    syntax: cache-rule name [key KEY] [ttl TTL] [code CODE] [if|unless condition]

    default: none

    context: backend, listen

    定义缓存规则。可以同时定义多个,但是需要注意顺序,匹配则会停止测试。

    acl pathA path /a.html
    filter cache
    cache-rule all ttl 3600
    cache-rule path01 ttl 60 if pathA
    

    path01这条规则永远不会执行,因为 all 会匹配所有的规则。

    name

    定义一个名字。

    key KEY

    定义 key,由以下关键字组成:

    • method: http method, GET/POST...
    • scheme: http or https
    • host: the host in the request
    • path: the URL path of the request
    • query: the whole query string of the request
    • header_NAME: the value of header NAME
    • cookie_NAME: the value of cookie NAME
    • param_NAME: the value of query NAME
    • body: the body of the request

    默认 key 是method.scheme.host.path.query.body

    Example

    GET http://www.example.com/q?name=X&type=Y
    
    http header:
    GET /q?name=X&type=Y HTTP/1.1
    Host: www.example.com
    ASDF: Z
    Cookie: logged_in=yes; user=nuster;
    

    会得到:

    • method: GET
    • scheme: http
    • host: www.example.com
    • path: /q
    • query: name=X&type=Y
    • header_ASDF: Z
    • cookie_user: nuster
    • param_type: Y
    • body: (empty)

    所以默认的 key 就会得到GEThttpwww.example.com/qname=X&type=Y, 而 key method.scheme.host.path.header_ASDF.cookie_user.param_type则会生成 GEThttpwww.example.com/qZnusterY

    一个请求的 key 能在缓存中找到则返回缓存内容。

    ttl TTL

    定义 key 的失效时间,可以使用 d, h, m and s。默认3600秒. 如果不希望失效则设为 0

    code CODE1,CODE2...

    默认只缓存 200 的响应,如果需要缓存其他的则可以添加,all会缓存任何状态码。

    cache-rule only200
    cache-rule 200and404 code 200,404
    cache-rule all code all
    

    if|unless condition

    定义 ACL 条件 详见HAProxy configuration7. Using ACLs and fetching samples

    FAQ

    如何调试?

    global添加debug, 或者带-d启动haproxy

    缓存相关的调试信息以[CACHE]开头

    如何缓存 POST 请求?

    添加option http-buffer-request

    如果自定义了 key 的话需要使用body关键字

    请求 body 可能不完整,详见HAProxy configurationoption http-buffer-request小节

    另外可以为 post 请求单独设置一个后端

    Example

    global
        cache on data-size 100m
        #daemon
        ## to debug cache
        #debug
    defaults
        retries 3
        option redispatch
        timeout client  30s
        timeout connect 30s
        timeout server  30s
    frontend web1
        bind *:8080
        mode http
        acl pathPost path /search
        use_backend app1a if pathPost
        default_backend app1b
    backend app1a
        balance roundrobin
        # mode must be http
        mode http
    
        # http-buffer-request must be enabled to cache post request
        option http-buffer-request
    
        acl pathPost path /search
    
        # enable cache for this proxy
        filter cache
    
        # cache /search for 120 seconds. Only works when POST/PUT
        cache-rule rpost ttl 120 if pathPost
    
        server s1 10.0.0.10:8080
    backend app1b
        balance     roundrobin
        mode http
    
        filter cache on
    
        # cache /a.jpg, not expire
        acl pathA path /a.jpg
        cache-rule r1 ttl 0 if pathA
    
        # cache /mypage, key contains cookie[userId], so it will be cached per user
        acl pathB path /mypage
        cache-rule r2 key method.scheme.host.path.query.cookie_userId ttl 60 if pathB
    
        # cache /a.html if response's header[cache] is yes
        http-request set-var(txn.pathC) path
        acl pathC var(txn.pathC) -m str /a.html
        acl resHdrCache1 res.hdr(cache) yes
        cache-rule r3 if pathC resHdrCache1
    
        # cache /heavy for 100 seconds if be_conn greater than 10
        acl heavypage path /heavy
        acl tooFast be_conn ge 100
        cache-rule heavy ttl 100 if heavypage tooFast 
    
        # cache all if response's header[asdf] is fdsa
        acl resHdrCache2 res.hdr(asdf)  fdsa
        cache-rule resCache ttl 0 if resHdrCache1
    
        server s1 10.0.0.10:8080
    
    frontend web2
        bind *:8081
        mode http
        default_backend app2
    backend app2
        balance     roundrobin
        mode http
    
        # disable cache on this proxy
        filter cache off
        cache-rule all
    
        server s2 10.0.0.11:8080
    
    listen web3
        bind *:8082
        mode http
    
        filter cache
        cache-rule everything
    
        server s3 10.0.0.12:8080
    
    
    1 条回复    2018-08-17 14:25:11 +08:00
    inyu
        1
    inyu  
       2018-08-17 14:25:11 +08:00
    这个不错
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1556 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 23ms · UTC 17:07 · PVG 01:07 · LAX 09:07 · JFK 12:07
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.