缓存、队列:Memcached

2022-04-13 00:00:00 数据 获取 内存 启动 安装

本章内容:

  • Memcached 

    •  简介、安装、使用

    •  Python 操作 Memcached

    •  天生支持集群

1、简介、安装、使用

  Memcached 是一个高性能的分布式内存对象缓存系统,用于动态 Web 应用以减轻数据库负载压力。它通过在内存中缓存数据和对象来减少读取数据库的次数,从而提高动态、数据库驱动网站的速度。Memcached 基于一个存储键/值对的 hashmap。其守护进程(daemon )是用 C 写的,但是客户端可以用任何语言来编写,并通过 memcached 协议与守护进程通信。

 

Memcached 内存管理机制:
       Menceched 通过预分配指定的内存空间来存取数据,所有的数据都保存在 memcached 内置的内存中。
  利用 Slab Allocation 机制来分配和管理内存。按照预先规定的大小,将分配的内存分割成特定长度的内存块,再把尺寸相同的内存块分成组,这些内存块不会释放,可以重复利用。
  当存入的数据占满内存空间时,Memcached 使用 LRU 算法自动删除不是用的缓存数据,即重用过期数据的内存空间。Memcached 是为缓存系统设计的,因此没有考虑数据的容灾问题,和机器的内存一样,重启机器将会丢失,如果希望服务重启数据依然能保留,那么就需要 sina 网开发的 Memcachedb 持久性内存缓冲系统,当然还有常见的 NOSQL 服务如 redis。
默认监听端口:11211

 

Memcached 安装

    wget http://memcached.org/latest
    tar -zxvf memcached-1.x.x.tar.gz
    cd memcached-1.x.x
    ./configure && make && make test && sudo make install

    PS:依赖libevent
    yum install libevent-devel
    apt-get install libevent-dev

    源码安装启动 Memcached 快速部署文档

      # Memcached 服务安装


      # 1、安装libevent
      mkdir /home/oldsuo/tools/
      cd /home/oldsuo/tools/
      wget http://down1.chinaunix.net/distfiles/libevent-2.0.21-stable.tar.gz
      ls libevent-2.0.21-stable.tar.gz
      tar zxf libevent-2.0.21-stable.tar.gz
      cd libevent-2.0.21-stable
      ./configure
      make && make install
      echo $?
      cd ..


      # 2、安装Memcached
      wget http://memcached.org/files/memcached-1.4.24.tar.gz
      tar zxf memcached-1.4.24.tar.gz
      cd memcached-1.4.24
      ./configure
      make
      make install
      echo $?
      cd ..


      # PS :
      memcached-1.4.24.tar -->客户端
      memcached-1.4.24.tar.gz -->服务端


      # 3、启动及关闭服务
      echo "/usr/local/lib" >> etc/ld.so.conf
      ldconfig


      # 查看帮助
      /usr/local/bin/memcached –h


      # 启动Memcached服务
      memcached -p 11211 -u root -m 16m -c 10240 –d


      # 查看启动状态
      lsof -i :11211


      # 关闭服务
      pkill memcached
      # memcached -p 11212 -u root -m 16m -c 10240 -d -P var/run/11212.pid
      # kill `cat var/run/11212.pid`


      # PS:开机自启动把上述启动命令放入/etc/rc.local

      源码安装 Memcached PHP 客户端

        # Memcached PHP 客户端安装


        cd /home/oldsuo/tools/
        wget http://pecl.php.net/get/memcache-3.0.7.tgz
        tar zxf memcache-3.0.7.tgz
        cd memcache-3.0.7
        /application/php/bin/phpize
        ./configure --enable-memcahce --with-php-config=/application/php/bin/php-config --with-zlib-dir
        make
        make install


        # 安装完成后会有类似这样的提示:
        Installing shared extensions: application/php5.3.27/lib/php/extensions/no-debug-zts-20131226/
        [root@localhost memcache-3.0.7]# ll application/php5.3.27/lib/php/extensions/no-debug-zts-20131226/
        total 1132
        -rwxr-xr-x 1 root root 452913 Nov 17 16:52 memcache.so
        -rwxr-xr-x. 1 root root 157862 Oct 9 21:01 mysql.so
        -rwxr-xr-x. 1 root root 542460 Oct 9 19:25 opcache.so


        # 编辑php.ini文件,添加extension = memcache.so 一行
        vim /application/php/lib/php.ini
        Extension_dir = "/application/php5.3.27/lib/php/extensions/no-debug-zts-20131226/"
        extension = memcache.so


        # 重启 apache 服务是PHP的配置生效
        [root@localhost application]# usr/local/apache/bin/apachectl -t
        Syntax OK
        [root@localhost application]# usr/local/apache/bin/apachectl graceful
        Memcached 启动


        memcached -d -m 10 -u root -l 218.97.240.118 -p 12000 -c 256 -P tmp/memcached.pid

        参数说明:
        -d 是启动一个守护进程
        -m 是分配给Memcache使用的内存数量,单位是MB
        -u 是运行Memcache的用户
        -l 是监听的服务器IP地址
        -p 是设置Memcache监听的端口,好是1024以上的端口
        -c 选项是大运行的并发连接数,默认是1024,按照你服务器的负载量来设定
        -P 是设置保存Memcache的pid文件

        Memcached 启动

          memcached -d -m 10 -u root -l 218.97.240.118 -p 12000 -c 256 -P tmp/memcached.pid

          参数说明:
          -d 是启动一个守护进程
          -m 是分配给Memcache使用的内存数量,单位是MB
          -u 是运行Memcache的用户
          -l 是监听的服务器IP地址
          -p 是设置Memcache监听的端口,好是1024以上的端口
          -c 选项是大运行的并发连接数,默认是1024,按照你服务器的负载量来设定
          -P 是设置保存Memcache的pid文件

          Memcached 命令

            存储命令: set/add/replace/append/prepend/cas
            获取命令: get/gets
            其他命令: delete/stats..

             Memcached 管理

              #1、telnet ip port 方式管理
              telnet 127.0.0.1 11211


              #2、命令直接操作,nc这样的命令
              [root@localhost application]# printf "stats slabs\r\n"|nc 127.0.0.1 11211
              STAT active_slabs 0
              STAT total_malloced 0
              END


              #3、管理 Memcached 命令
              a、stats 统计Memcached的各种信息。
              b、stats reset 重新统计数据,重新开始统计。
              c、stats slabs 显示slabs信息。通过这命令能获取每个slabs的chunksize长度,从而确定数据保存在哪个slab。
              d、stats items 显示slab中的item数目。
              e、stats setting 查看一些Memcached设置,列如线程数….
              f、stats slabs 查看slabs相关情况。
              g、stats sizes 查看存在Item个数和大小。
              h、stats cachedump 查看key value
              i、stats reset 清理统计数据。
              j、set|get,gets 用来保存或获取数据。

              Memcached memadmin php工具界面化管理安装部署文档

                # memadmin php 工具管理(memcadmin-1.0.12.tar.gz)


                1、安装memadmin php工具。
                cd /home/oldsuo/tools
                wget http://www.junopen.com/memadmin/memadmin-1.0.12.tar.gz
                tar zxf memadmin-1.0.12.tar.gz -C usr/local/apache/htdocs/
                ll /usr/local/apache/htdocs/memadmin/


                2、 登陆memadmin php。
                web方式访问:http://IP地址/memadmin/
                默认用户名密码都为admin。

                2、Python 操作 Memcached 

                安装 API 及 基本操作

                python 操作 Memcached 使用 Python-memcached 模块
                下载安装:https://pypi.python.org/pypi/python-memcached
                  import memcache

                  mc = memcache.Client(['192.168.1.5:12000'], debug=True)
                  mc.set("foo", "bar")
                  ret = mc.get('foo')
                  print ret

                   

                  2> 天生支持集群

                  python-memcached 模块原生支持集群操作,其原理本质是在内存维护一个主机列表,数字为权重,为3即出现3次,相对应的几率大

                    mc = memcache.Client([
                    ('192.168.1.5:12000', 3), # 数字为权重
                    ('192.168.1.9:12000', 1),
                    ], debug=True)


                    # 那么在内存中主机列表为:
                    # host_list = ["192.168.1.5","192.168.1.5","192.168.1.5","192.168.1.9",]

                     

                    那么问题来了,集群情况下如何选择服务器存储呢?
                    如果要创建设置一个键值对(如:k1 = "v1"),那么它的执行流程如下:
                    1. 将 k1 转换成一个数字
                    2. 将数字和主机列表的长度求余数,得到一个值 N(N 的范围:0 <= N < 列表长度 )
                    3. 在主机列表中根据 第2步得到的值为索引获取主机,例如:host_list[N]
                    4. 连接 将第3步中获取的主机,将 k1 = "v1" 放置在该服务器的内存中
                    获取值的话也一样
                    源码、将字符串转换为数字
                      #!/usr/bin/env python
                      #-*- coding:utf-8 -*-
                      __author__ = 'Nick Suo'


                      import binascii


                      str_input = 'suoning'
                      str_bytes = bytes(str_input, encoding='utf-8')
                      num = (((binascii.crc32(str_bytes) & 0xffffffff) >> 16) & 0x7fff) or 1
                      print(num)

                       

                      add

                      添加一个键值对,如果 key 已经存在,重复添加执行 add 则抛出异常

                        import memcache

                        mc = memcache.Client(['192.168.1.5:12000'], debug=True)
                        mc.add('k1', 'v1')
                        # mc.add('k1', 'v2') # 报错,对已经存在的key重复添加,失败!!!

                         

                        replace

                        replace 修改某个 key 的值,如果 key 不存在,则异常

                          import memcache

                          mc = memcache.Client(['192.168.1.5:12000'], debug=True)
                          # 如果memcache中存在kkkk,则替换成功,否则一场
                          mc.replace('kkkk','999')

                           

                          set 和 set_multi

                          set             设置一个键值对,如果 key 不存在,则创建
                          set_multi   设置多个键值对,如果 key 不存在,则创建

                            import memcache

                            mc = memcache.Client(['192.168.1.5:12000'], debug=True)

                            mc.set('name', 'nick')
                            mc.set_multi({'name': 'nick', 'age': '18'})

                             

                            delete 和 delete_multi

                            delete              删除指定的一个键值对
                            deete_multi    删除指定的多个键值对

                              import memcache

                              mc = memcache.Client(['192.168.1.5:12000'], debug=True)

                              mc..delete('name', 'nick')
                              mc.delete_multi({'name': 'nick', 'age': '18'})

                               

                              get 和 get_multi

                              get             获取一个键值对
                              get_multi   获取多个键值对

                                import memcache

                                mc = memcache.Client(['192.168.1.5:12000'], debug=True)

                                val = mc.get('name')
                                item_dict = mc.get_multi(["name", "age",])

                                 

                                append 和 prepend

                                append    修改指定key的值,在该值 后面 追加内容
                                prepend   修改指定key的值,在该值 前面 插入内容

                                  import memcache

                                  mc = memcache.Client(['192.168.1.5:12000'], debug=True)
                                  # 原始值:k1 = "v1"


                                  mc.append('k1', 'after')
                                  # k1 = "v1after"

                                  mc.prepend('k1', 'before')
                                  # k1 = "beforev1after"

                                   

                                  decr 和 incr

                                  incr  自增,将 Memcached 中的某个值增加 N ( N 默认为1 )
                                  decr 自减,将 Memcached 中的某个值减少 N ( N 默认为1 )
                                    import memcache

                                    mc = memcache.Client(['192.168.1.5:12000'], debug=True)
                                    mc.set('k1', '666')

                                    mc.incr('k1')
                                    # k1 = 667

                                    mc.incr('k1', 10)
                                    # k1 = 677

                                    mc.decr('k1')
                                    # k1 = 676

                                    mc.decr('k1', 10)
                                    # k1 = 666

                                    gets 和 cas
                                    这两个方法就是传说中的 锁 
                                    为了避免脏数据的产生而生
                                      import memcache
                                      mc = memcache.Client(['192.168.1.5:12000'], debug=True, cache_cas=True)

                                      v = mc.gets('product_count')
                                      # 如果有人在gets之后和cas之前修改了product_count,那下面的设置将会执行失败,剖出异常
                                      mc.cas('product_count', "899")
                                      本质:每次执行 gets 时,就从 memcache 中获取一个自增的数字,通过 cas 去修改 gets 到的值时,会携带之前获取的自增值和 memcache 中的自增值进行比较,如果相等,则可以提交,如果不相等,那表示在 gets 和 cas 执行之间,又有其他人执行了 gets(获取了缓冲的指定值),如此一来有可能出现非正常的数据,则不允许修改,并报错。

                                      来源 https://www.modb.pro/db/149631

                                      相关文章