设为首页 收藏本站
查看: 934|回复: 0

[经验分享] memcached+varnish

[复制链接]
累计签到:1 天
连续签到:1 天
发表于 2016-8-17 09:25:25 | 显示全部楼层 |阅读模式
memcached
缓存服务器:
        1.缓存:cache,无持久存储功能
        2.行挂失缓存bypass,而不是代理式缓存
        3.仅提供缓存功能,存什么,怎么存全有客户端决定
        4.k/v cache,只能存储可序列化数据
        5.存储项是非常简单的:key,value,flag,expire time(过期时间)单数上限:1M
        6.功能的实现一把依赖于memcached,一半是client
        7.不能高可用,挂了缓存就丢失了
        8.O(1)的执行效率
        9.分布式缓存互不通信的分布式集群
                        分布式系统请求路由方法:取膜法,一致性哈希算法
        10.缓存耗尽时基于LRU(最近最少使用)清理
        缓存过期项:惰性清理机制,新的直接覆盖旧的
memcached协议
        客户端要拥有连接memcached的适配器php-memcached

yum安装就好

配置文件/etc/sysconfig/memcached
        默认监听11211/tcp,11211/udp

主程序 /usr/bin/memcached


协议格式:
        文本格式
        二进制格式

telnet文本交互:

        常用命令

                统计类:stats items | slabs |sizes

                存储类:set,add,replace,append,perpend

                获取数据类:get,delete,incr/decr

                清空:flesh_all


                add mykey 0 30 5  添加mykey
                hello                          内容hello
                set mykey 0 30 5  设置mykey的值
                hello
                get mykey                  获取mykey值

                                  0:标志位
                                    30:缓存ttl值时长,30秒后无法获得
                                       5:整个数据的长度

                append mykey 0 300 11   追加内容,注意长度的修改,是指添加了多少个字符而不是添加到

                prepend mkkey 0 300 3  同上,只不过是在前边添加,想要两个值之间带空格就在字符数多几个字符



                incr key_name #  将key的值+1  key值要是数字
                decr          #           -1

                                                (常用于微博微信之类的赞转发之类的计数)

                flush all  清空缓存




程序常用选项

        -m #:缓存空间大小,单位mb默认64
        -c #:并发连接数,默认1024
        -u username:程序运行者身份,一般要用普通用户
        -p Port:监听的tcp端口
        -u Port:监听的udp端口
        -l ip_addr:监听的IP地址,默认本机所有IP地址
        -M :一旦缓存空间耗尽的时候,想请求存储缓存项换回错误信息,而非使用默认的lru算法
        -f factor :用来指明chunk的增长因子,默认是1.25
        -vv:详细内容
        -t #:线程数量,默认为4,最好<cpu数


启动服务一般选项

memcached -u    -p    -m   -c   $options

在环境文件中配置后,直接memcached就行
        /etc/sysconfig/memcached
options项写-a xxx之类的就行












memcached的认证功能
        默认没有认证机制,可以借助SASL进行认证

                SASL:简单安全认证层


API:C++:libmemcached(c语言)
         php:memcached:php-pecl-memcached
                   memcache :php-pecl-memcache














Varnish:web cache (page cache)

中小型web应用架构 图


线程限制是针对域名来说的,单域名双线程,所以,多个域名也可以提升性能


程序运行具有局部性特征
        空间局部性:
                某一个数据被访问过,离他较近的数据也有可能被访问到
        时间局部性:
                某一个数据被访问到,随后有可能很快会被再次访问到

热区:一段时间内会有一个特别流行的数据,80%的访问量被20%的数据承载(尤其是电商,流行商品,淘宝爆款),这些就叫热区,其实就是局部性的表现,体现出缓存的价值,因为缓存主要存放的及时热区数据

时效性:缓存是会过期的,所以要具备过期处理逻辑
        缓存清理:
                过期清理
                缓存溢出清理:LRU最近最少使用



        缓存就是利用空间换取时间,在较短的时间内快速获得结果

缓存命中率:命中次数/未命中次数+命中次数
        (0,1)

        页面命中率:基于页面数量进行衡量
        字节命中率:基于页面的大小,体积进行衡量
                以上要有一个是收益OK的,那么缓存就是有效的


缓存与否:
        私有数据:private,例如邮箱等:只能放在私有缓存中
        公共数据:public,例如电商的商品页面:放在私有缓存和公有缓存

缓存种类:
        私有缓存:浏览器缓存
        公有缓存:reverse proxy,cache

如何分辨私有公有:
        带有某个标签或者是存在cookie的都是私有的,没有的就被认定是公有的

缓存处理的步骤

        接受请求--->解析请求(提取请求首部中的URL及其他首部)---->查询缓存--->新鲜度检测(是不是在有效期)--->检查元数据是不是改变,如果没改变--->构建响应报文-->发送响应--->记录日志(类似于httpd的combined)


过期检查机制:

        每个缓存都是会有服务器加一个过期时间.在这个时间内都是有缓存返回的,如果过期了或者没有缓存,就反代到后端服务器,后端服务器发送数据和过期时间给缓存和请求

        首部:HTTP/1.0
                Expire:绝对时间:xxx-xxx
                HTTP/1.1
                Cache-Control:maxage=相对时长,过多长时间过期
                Cache-Control:s-maxage=公共缓存时长

条件检查机制:validation

        (1)LASTMODIFIED:最近修改时间

           IF MOFIFIED SINCE:从上次开始是不是修改过时间

           请求数据到缓存服务器上,如果超出有效时间,缓存服务器向后端服务器发送一个请求报文,询问是不是修改了,如果是,就由后端服务器来发送数据,没有的话就是有缓存发送

        (2)Etag:资源标签

           if-none-match:标签有没变换

           基本上和上边相同,只是寻问的是标签有没有变化


两者结合:超时有效时长的,向后端服务器发送条件检查



开源解决方案:
        squid:
        varnish:在非常大的并发连接数下,varnish不是很稳定


varnish:绝大多数站点都是varnish www.varnish-cache.org 最新稳定版本4.1.3 (分支5.0|4.1|4.0)



Architecture        图








组织架构
        management进程
        child/cache进程:包含多种类型的线程
                accept worker expiry
        shared memeory log:
                统计数据的计数器
                日志区域

配置接口:VCL
        VCL complier--->c complier------->shared object

上午第二节课


环境文件
        配置文件
                /etc/varnish/default.vcl配置缓存工作(child/cache)
                /etc/varnish/varnish.params配置varnish自身(端口之类的)
        主程序

        CLI interface
                varnishadm

        shared log
                /usr/bin/varnishhist
                /usr/bin/varnishlog
                /usr/bin/varnishncsa
                /usr/bin/varnishstat
                /usr/bin/varnishtest
                /usr/bin/varnishtop


        varnishtest:模拟varnish的客户端,测试varnish的工作是不是正常

        systemd unitfile
                varnish.service

                varnishlog
                varnishncsa:日志持久化服务,每个多长时间读取次日志


varnish的缓存存储机制
        (1)malloc[,size]
                内存存储
        (2)file[path[,size[,granularity]]]
                文件存储,黑盒,重启后缓存失效
        (3)persistent,path,size
                文件存储,黑盒,重启不失效,但是还在测试



varnish程序的选项
        (1)程序选项 /etc/varnish/varnish.params
                -a IP地址:port
                        服务接口,不能是127,默认6081
                -T IP地址:port
                        管理接口,默认6082
                -s [name]=type[,options]
                        定义缓存存储机制
                -u user
                -g group
                        定义运行身份
                -f config
                        VCL配置文件
                -F
                        前台运行
        (2)运行时参数(运行时可以更改的)
                -p param=value
                -r param[,param..]运行时不可以更改,只读

                大多数运行参数都有默认值不用设定,必要设定时候要在varnish.params定义,在程勋运行前定义
                在底下的DEMON_OPTS
                例如:
                #DAEMON_OPTS="-p thread_pool_min=5 -p thread_pool_max=500 -p thread_pool_timeout=300"


        具体配置

                6081可以改
                6082是管理接口,也可以改

                #DAEMON_OPTS="-p thread_pool_min=5 -p thread_pool_max=500 -p thread_pool_timeout=300"
                最小/最大线程池数量,超时时间


                VARNISH_STORAGE="file,/var/lib/varnish/varnish_storage.bin,1G"
                文件存储

                VARNISH_STORAGE="malloc,1G"
                内存存储


事实上大多时候都不需要更改直接使用,主要还是VCL


        varnish_reload_vcl:vcl配置文件重载程序



        varnishadm -S /etc/varnish/sercet -T address:port

        help获取命令列表

        配置文件相关
                vcl.list:列出vcl文件有哪些
                        load:装载,加载并编译

                                vcl.load testconfig1 default.vcl

                        use:激活

                                vcl.use testconfig1  激活了,生效了

                        discard:删除,最好先激活另一个后在删除上一个
        运行时参数
                param.show:显示参数列表
                          show<param>显示某个参数配置
                          set<PARAM><VALUE>设定

        缓存存储
                storage.list

        后端服务器:
                backend.list


VCL:域专有类型的配置语言

        state engine:状态引擎

        VCL有多个状态引擎.且之间存在相关性,但是彼此间互相隔离,每个状态引擎可使用return指明关联至那个下一级引擎













        vcl_recv--->vcl_pipe
        收到后不知道做什么直接送到后端
        vcl_recv--->vcl_error
        收到后不允许给他数据或者直接请求就是错的


        vcl_pass:多加的处理逻辑,可以额外做一些处理的设定

        vcl_purge:缓存的修剪


varnish 4:
        vcl_recv ---->vcl_hash
                (1)hit:vcl_hit--->vcl_deliver
                (2)pass,hit for pass:vcl_pass--->vcl_backend_fetch-->_response-->vcl_deliver
                (3)miss:vcl_miss--->[vcl_pass--->]vcl_backend_fetch-->_response-->vcl_deliver
                (4)purge:vcl_purge--->vcl_synth
                (5)pipe:vcl_pipe
                (6)busy:vcl_waiting



vcl语法格式
        (1)支持注释符
                //:单行注释
                /*...*/:多行注释
                #:注释
        (2)sub $name:定义子例程;sub vcl_recv{..}只对vcl_recv有效
        (3)不支持循环,但是支持条件判断
        (4)有大量的內建变量,生效位置有特定要求
        (5)使用终止语句return决定下一个状态引擎;但是没有返回值
        (6)操作符
                =:赋值
                ==:等值判断
                !:取反
                ~:匹配
                &&:逻辑与
                ||:逻辑或
                >,<,>=,<=
        (7)语句使用;结尾



变量类型
        內建变量:
        req.*:request,由客户端发来的请求报文相关的众多数据
                req.http.*
                        req.http.User-Agent:客户端浏览器类型
                                        .Referer:从哪里引用过来的
                                        .method:get等
                各引擎都可用,都是只读只写
        bereq.*:backend 由varnish发给后端的请求
                        berep.http.*
        beresp.*:有后端响应给varnish的
                        beresp.http.*
        obj.*:发送给缓存服务器的
        resp.*:响应给前端请求的


        常用变量
                bereq.*:
                        bereq.http.HEADERS
                        bereq.request:请求方法
                                 .url:请求的url
                                 .proto:请求的协议版本
                                 .backend:指明要调用的后端主机
                beresp.*:
                        bereq.http.HEADERS
                                          .status:响应的状态码
                                          .proto:协议版本
                                          .backend.name:BE主机的主机名
                                          .ttl:BE主机响应内容的余下的可缓存时长
                obj.*:
                        obj.hits:当前正在访问的缓存的命中次数(这一次)
                                .ttl:对象的ttl值,缓存时长

                server.*
                        server.ip
                                  .hostname
                client.*
                                .ip

下午第一节课
        set:设置一个变量
        unset:取消一个变量


        用户自定义:
                事例1:强制对某类资源的请求不检查缓存
                        vcl_recv{
                        if (req.url ~ "(?i)^/(login|admin)") {
                                return(pass);
                                }
                        }


        事例2:对于特定类型的资源,例如公开的图片等,取消其私有标志,并强行设定器可以由varnish缓存的时长

                        vcl_backend_response{
                        if (beresp.http.caceh-control !~ "s-maxage") {
                                if (bereq.url ~ "(?i)\.(jpg|jpeg|png|gif|css|js)$") {
                                unset beresp.http.Set-Cppkie;
                                set beresp.ttl=3600s;
                                        }
                                }

                        }



        缓存对象的修剪:purge ban

                purge:

                (1)sub vcl_purge {
                        return(synth(200,"purged自己定义"));
                }                                               

                (2)要在recv中定义那些请求到purge中
                        if (req.method == "PURGE") {
                                        return(purge);
                        }

                (3)定义访问控制列表
                        acl purgers {
                                "127.0.0.0"/8;
                                "172.16.0.0"/16;
                        }

                        sub vcl_recv {
                                if (req.method == "PURGE") {
                                        if(!dlient.ip ~ purgers){
                                                return(405,"Purging not allowed for" = + client.ip));
                                        }
                                }
                        }



        如何设定使用多个后端主机:
                backend name {
                        .host = " ";
                        .port = " ";
                }

                sub vcl_recv {
                        if (req.url ~ "(?i)\.php$") {
                        set req.backend_hint = appsrv;
                                } else {
                        set req.backend_hint = default;
                                }       

                        }
                }



后端多个主机不做分离式做负载均衡

varnish做director

        varnish module
                使用前要先导入
                        import directors


        sub vcl_init:处理任何请求之前要执行的vcl代码,主要用于初始化VMODs
            vcl_fini:所有的请求都退出后,在vcl配置被丢弃的时候处理调用,主要用于清理VMODs

            调度方法:random,hash,round_robin()

            import directors;

            sub vcl_init{
            newbar = director.round_robin();
            自定义组名          .调度算法
            bar.add_backend(server1);
            bar.add_backend(server2);
            }


            sub vcl_recv {
                    set req.backend_hint = newbar.backend();
            }



        BE健康状态检查

                backend BE_NAME{
                .host
                .port
                .probe={
                        .url:检测要请求的url,默认为主页
                        .request:指明打出请求报文怎么发
                        .timeout:检测的超时时长
                        .inteval:检查频度,多长时间检查一次
                        .window = #:基于最近的多少次检查判断健康状态
                        .threshold = #:至少几次是成功才认定是健康的
                        .expected_response:期望的响应码,默认是200
                }
                }

                也可以
                probe NAME {
                        .url:检测要请求的url,默认为主页
                        .request:指明打出请求报文怎么发
                        .timeout:检测的超时时长
                        .inteval:检查频度,多长时间检查一次
                        .window = #:基于最近的多少次检查判断健康状态
                        .threshold = #:至少几次是成功才认定是健康的
                        .expected_response:期望的响应码,默认是200

                }

                然后在.host下边
                        .probe = NAME;





varnish的运行时参数:查看参数 param.show -l
        线程模型:
                cache-worker
                cache-main
                ban lurker
                acceptor
                epoll/kqueue*
                ...


        线程相关的参数
                在线程池内部,其每一个请求有一个线程处理;其worker线程的最大数决定了varnish的并发响应能力

                thread_pools :线程池个数,小于等于cpu核心数
                thread_pool_max:调整每个线程池的最大工作线程数量,默认5000个
                        最大并发数上边两个相乘

                thread_pool_min:......

                param.set thread_poll_max 1000(但是重启不保存,编辑配置文件)


                        #DAEMON_OPTS="-p thread_pool_min=5 -p thread_pool_max=500 -p thread_pool_timeout=300"

                        记住要用-p指定,每一个都要,不可以一个-p指多个参数

                thread_poll_timeout:默认10秒

                                   _add_delay:创建线程之间要不要有间隔,默认0

                                   _destroy_delay:多长时间清理一个线程,默认10毫秒





客户端命令的使用
/usr/bin/varnishhist
/usr/bin/varnishlog
/usr/bin/varnishncsa
/usr/bin/varnishstat
/usr/bin/varnishtest
/usr/bin/varnishtop
        日志区域
                计数器

                日志信息



/usr/bin/varnishstat查看统计数据

        varnishstat -1:持续刷新类似watch -n
                                -f:指向显示那些字段,-1出来的都是字段
                                        -1 -f xxxx
                                -l:那些字段可以跟-f使用

                MAIN.cache_miss
                MAIN.cache_hit  重点关注的两项,可以计算命中率






/usr/bin/varnishtop显示日志,对日志做排序

        varnishtop -1:持续性显示
                           -i:查看指定标签信息,标签名去-1信息里边找,多个","隔开
                           -I:同-i,但是支持正表
                           -x:排除列表,不显示某个标签
                           -X:支持正表的-x


/usr/bin/varnishlog正儿八经的显示日志本身的

        varnishlog

/usr/bin/varnishncsa将日志以combined的格式显示,就是httpd的日志格式

        varnishncsa -f:指定日志记录什么,就是httpd的那些%的东西

        想保存起来就执行/usr/lib/systemd/system/varnishncsa.service

                        systemctl start varnishncsa.service



vcl可以做url重写,使用一个內建函数



一个客户端有多个域名,使用hash算法来命中
hash_data():指明hash计算的数据,减少差异以提升命中率
regsub(str,regex,sub):正则表达式的模式替换,吧str中第一次被regex匹配到的替换为sub
regsuball():全部替换,主要用于url重写

return()
ban(expression):清理缓存,后跟普通表达式
ban_url(regex):清理缓存,后跟正表

最后一节课最后的hash_data

synth(status,"string"):purge,一次只清理一个url缓存对象





实践作业
        前段nginx将用户请求调度到两个varnish,并保证命中率,hash他的url,map和consistent的hash算法,varnish要方向代理用户请求到后端主机,后端主机上部署以个wordpress,并且把请求分发到三个主机上的时候有什么不同







        生成静态页面,当服务器挂了,就定到静态页面服务器上,降级xx的概念


博客作业,以上所有内容



haproxy和tomcat






运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-259056-1-1.html 上篇帖子: memcached演练(5) 内存管理 下篇帖子: 安装memcached
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表