zoukankan      html  css  js  c++  java
  • python_Memcached

    一、Memcached

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

    Memcached安装和基本使用

    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:

    emcached -d -m 10    -u root -l 10.211.55.4 -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..

      Python操作Memcached

      安装API

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

       1、Memcached简单操作

      服务器端:

      启动Memcached:

      客户端:  

    import memcache
    mc = memcache.Client(["192.168.1.104:12000"],debug=True)
    mc.set("foo","lcj")
    ret = mc.get("foo")
    print(ret)
    #输出lcj

      Ps:debug = True 表示运行出现错误时,现实错误信息,上线后移除该参数。

      2、Memcached天生支持集群

      python-memcached模块原生支持集群操作,其原理是在内存维护一个主机列表,且集群中主机的权重值和主机在列表中重复出现的次数成正比

         主机    权重
        1.1.1.1   1
        1.1.1.2   2
        1.1.1.3   1
     
    那么在内存中主机列表为:
        host_list = ["1.1.1.1", "1.1.1.2", "1.1.1.2", "1.1.1.3", ]
    

     如果用户根据如果要在内存中创建一个键值对(如:k1 = "v1"),那么要执行一下步骤:

    • 根据算法将 k1 转换成一个数字
    • 将数字和主机列表长度求余数,得到一个值 N( 0 <= N < 列表长度 )
    • 在主机列表中根据 第2步得到的值为索引获取主机,例如:host_list[N]
    • 连接 将第3步中获取的主机,将 k1 = "v1" 放置在该服务器的内存中
    import memcache
    #服务器为3个主机,按照权重1,2,3进行运行
    mc = memcache.Client([("192.168.1.104:12000",1),("192.168.1.105:12000",2),("192.168.1.105:12000",3)],debug=False)
    mc.set("foo","lcj")
    ret = mc.get("foo")
    print(ret)
    

      3、Memcached常用方法

      1)add

      添加一条键值对,如果已经存在的 key,重复执行add操作异常  

    import memcache
    #服务器为192.168.1.104:12000
    mc = memcache.Client(["192.168.1.104:12000"],debug=True)
    mc.add("f1","xiaoluo")
    # mc.add("f1","xiaoluo") #报错:对已经存在的key进行重复添加,报:MemCached: while expecting 'STORED', got unexpected response 'NOT_STORED'
    ret = mc.get("f1")
    print(ret)
    #xiaoluo
    

      2)replace

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

    # !/usr/bin/env python
    # -*- coding:utf-8 -*-
    # Author:lcj
    import memcache
    #服务器为192.168.1.104:12000
    mc = memcache.Client(["192.168.1.104:12000"],debug=True)
    mc.replace("f1","alex")  #如果memcache中存在f1值,则替换成功,否则失败
    ret = mc.get("f1")
    print(ret)
    #alex
    

      3)set和set_multi

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

    import memcache
    #服务器为192.168.1.104:12000
    mc = memcache.Client(["192.168.1.104:12000"],debug=True)
    # mc.set("f1","alex")  #如果f1不存在,则创建,存在则报错
    mc.set_multi({'w1':'123','w2':'qq'})
    

      4)delete 和 delete_multi

      delete             在Memcached中删除指定的一个键值对  
      delete_multi    在Memcached中删除指定的多个键值对

    import memcache
    #服务器为192.168.1.104:12000
    mc = memcache.Client(["192.168.1.104:12000"],debug=True)
    mc.delete('f1')  #删除f1中值
    ret = mc.get('f1')
    print(ret) #输出:None  
    import memcache
    #服务器为192.168.1.104:12000
    mc = memcache.Client(["192.168.1.104:12000"],debug=True)
    # mc.delete('f1')  #删除f1中值
    mc.delete_multi('f1','f2') #删除f1,f2中值
    

      5)get和get_multi

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

    import memcache
    #服务器为192.168.1.104:12000
    mc = memcache.Client(["192.168.1.104:12000"],debug=True)
    ret = mc.get('f2')
    print(ret)  #123
    item_dict = mc.get_multi(['f1','f2','f3','f4'])
    print(item_dict) #{'f3': '1234', 'f4': '1254', 'f2': '123'}
    

      6)append 和 prepend

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

    import memcache
    #服务器为192.168.1.104:12000
    mc = memcache.Client(["192.168.1.104:12000"],debug=True)
    mc.append('f2','xiaoluo') #append:在原来key值后面追加元素
    ret = mc.get('f2')
    print(ret) #123xiaoluo
    mc.prepend('f2','alex') #prepend:在指定key前添加元素
    ret = mc.get('f2')
    print(ret) #alex123xiaoluoxiaoluo
    

      7)decr 和 incr

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

    import memcache
    #服务器为192.168.1.104:12000
    mc = memcache.Client(["192.168.1.104:12000"],debug=True)
    mc.incr('f4','555')  #incr:将f4key值自增555
    ret = mc.get('f4')
    print(ret)
    mc.decr('f4','555')#decr:将f4key值自减555
    ret = mc.get('f4')
    print(ret)
    

      8)gets 和 cas

      如商城商品剩余个数,假设改值保存在memcache中,product_count = 900
      A用户刷新页面从memcache中读取到product_count = 900
      B用户刷新页面从memcache中读取到product_count = 900

      如果A、B用户均购买商品

      A用户修改商品剩余个数 product_count=899
      B用户修改商品剩余个数 product_count=899

      如此一来缓存内的数据便不在正确,两个用户购买商品后,商品剩余还是 899
      如果使用python的set和get来操作以上过程,那么程序就会如上述所示情况!

    import memcache
    #服务器为192.168.1.104:12000
    mc = memcache.Client(["192.168.1.104:12000"],debug=True,cache_cas=True)
    v = mc.gets('product_count')
    print(v)
    # 如果有人在gets之后和cas之前修改了product_count,那么,下面的设置将会执行失败,剖出异常,从而避免非正常数据的产生
    mc.cas('product_count','899')
    ret = mc.gets('product_count')
    print(ret)
    

      Ps:本质上每次执行gets时,会从memcache中获取一个自增的数字,通过cas去修改gets的值时,会携带之前获取的自增值和 memcache中的自增值进行比较,如果相等,则可以提交,如果不想等,那表示在gets和cas执行之间,又有其他人执行了gets(获取了缓冲的指 定值), 如此一来有可能出现非正常数据,则不允许修改。

  • 相关阅读:
    龙井和碧螺春的功效与作用
    064 01 Android 零基础入门 01 Java基础语法 08 Java方法 02 无参带返回值方法
    063 01 Android 零基础入门 01 Java基础语法 08 Java方法 01 无参无返回值方法
    062 01 Android 零基础入门 01 Java基础语法 07 Java二维数组 01 二维数组应用
    061 01 Android 零基础入门 01 Java基础语法 06 Java一维数组 08 一维数组总结
    060 01 Android 零基础入门 01 Java基础语法 06 Java一维数组 07 冒泡排序
    059 01 Android 零基础入门 01 Java基础语法 06 Java一维数组 06 增强型for循环
    058 01 Android 零基础入门 01 Java基础语法 06 Java一维数组 05 案例:求数组元素的最大值
    057 01 Android 零基础入门 01 Java基础语法 06 Java一维数组 04 案例:求整型数组的数组元素的元素值累加和
    056 01 Android 零基础入门 01 Java基础语法 06 Java一维数组 03 一维数组的应用
  • 原文地址:https://www.cnblogs.com/lcj0703/p/5697689.html
Copyright © 2011-2022 走看看