Python 之Memcache中间件

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

安装Memacahed


由于memcached依赖于libevent;因此,还需要安装libevent,命令如下:

root@devops:/opt# wget http://memcached.org/latest    # 下载软件包
root@devops:/opt# tar zxf memcached-1.5.9.tar.gz
root@devops:/opt# cd memcached-1.5.9/
root@devops:/opt/memcached-1.5.9# ./configure
root@devops:/opt/memcached-1.5.9# make && make install

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

启动Memacahed

root@devops:~# memcached -d -m 10 -u root 1 10.211.55.20 -p 1200 -c 256 -P /tmp/memcached.pid
root@devops:~# netstat -anpt | grep 1200
tcp        0      0 0.0.0.0:1200            0.0.0.0:*               LISTEN      9129/memcached
tcp6       0      0 :::1200                 :::*                    LISTEN      9129/memcached

参数说明:
    -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..

安装API

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

首次操作(小激动)

#!/usr/bin/env python
-*- coding: utf-8 -*-

import memcache

mc = memcache.Client(['10.211.55.20:1200'],debug=True)   # 连接memcached服务器

mc.set("foo","bar")
ret = mc.get("foo")
print(ret)

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

天生支持集群

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
mc = memcache.Client([('1.1.1.1:12000', 1), ('1.1.1.2:12000', 2), ('1.1.1.3:12000', 1)], debug=True)

mc.set('k1', 'v1')

add

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

#!/usr/bin/env python
-*- coding: utf-8 -*-

import memcache

mc = memcache.Client(['10.211.55.20:1200'],debug=True)

mc.set("foo","bar")
mc.add("foo","bar")
ret = mc.get("foo")
print(ret)

结果

/usr/local/bin/python3.6 /Users/xcn/PycharmProjects/oldboy/中间件开发/memcached-1.py
bar
MemCached: while expecting 'STORED', got unexpected response 'NOT_STORED'

repiace

repiace 修改某个key址,如果key不存在,则异常

#!/usr/bin/env python
-*- coding:utf-8 -*-
import memcache

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

set 和 set_multi

  • set : 设置一个键值对,如果key不存在,则创建,如果key存在,则修改
  • set_multi : 设置一个键值对,如果key不存在,则创建,如果key存,则修改
#!/usr/bin/env python
-*- coding:utf-8 -*-
import memcache

mc = memcache.Client(['10.211.55.20:1200'], debug=True)

mc.set('key0', 'john')

mc.set_multi({'key1': 'val1', 'key2': 'val2'})

delete 和 delete_multi

  • delete : 在Memcached中删除指定的一个键值对
  • delete_multi : 在Memcached中删除指定的多个键值对
#!/usr/bin/env python
-*- coding:utf-8 -*-
import memcache

mc = memcache.Client(['10.211.55.20:1200'], debug=True)

mc.delete('key0')
mc.delete_multi(['key1', 'key2'])

get 和 get_multi

  • get: 获取一个键值对
  • get_multi: 获取多一个键值对
#!/usr/bin/env python
-*- coding:utf-8 -*-
import memcache

mc = memcache.Client(['10.211.55.20:1200'], debug=True)

val = mc.get('key0')
item_dict = mc.get_multi(["key1", "key2", "key3"])

append 和 prepend

  • append : 修改指定key的值,在该值 后面 追加内容
  • prepend :修改指定key的值,在该值 前面 插入内容
#!/usr/bin/env python
-*- coding:utf-8 -*-
import memcache

mc = memcache.Client(['10.211.55.20:1200'], debug=True)
k1 = "v1"

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

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

decr 和 incr

#!/usr/bin/env python
-*- coding:utf-8 -*-
import memcache

mc = memcache.Client(['10.211.55.20:1200'], debug=True)
mc.set('k1', '777')

mc.incr('k1')
k1 = 778

mc.incr('k1', 10)
k1 = 788

mc.decr('k1')
k1 = 787

mc.decr('k1', 10)
k1 = 777

gets 和 cas

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

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

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

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

如果想要避免此情况的发生,只要使用 gets 和 cas 即可,如:

#!/usr/bin/env python
-*- coding:utf-8 -*-
import memcache
mc = memcache.Client(['10.211.55.20:1200'], debug=True, cache_cas=True)

v = mc.gets('product_count')
...

如果有人在gets之后和cas之前修改了product_count,那么,下面的设置将会执行失败,剖出异常,从而避免非正常数据的产生
mc.cas('product_count', "899")

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

Original: https://www.cnblogs.com/baishuchao/p/9398540.html
Author: baishuchao
Title: Python 之Memcache中间件

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/612114/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

  • CPU架构对redis的性能影响

    CPU架构对redis的性能影响 主流CPU架构 一个CPU处理器中通常有多个运行核心,每一个运行核心称为一个物理核,每个物理核都可以运行应用程序。每个物理核都拥有 私有的一级缓存…

    Linux 2023年5月28日
    099
  • 快速部署LAMP黄金架构,搭建disuz论坛

    404. 抱歉,您访问的资源不存在。 可能是网址有误,或者对应的内容被删除,或者处于私有状态。 代码改变世界,联系邮箱 contact@cnblogs.com 园子的商业化努力-困…

    Linux 2023年6月7日
    049
  • 008 Linux 文件查找 find

    在 Linux 系统,find 毫无疑问是最强的文件查找工具。find 一般会与其他命令结合,将查找到的结果作为参数传入到后置命令中,进行删除、统计、复制迁移等操作。 find /…

    Linux 2023年5月27日
    088
  • powershell版,Fail2Ban脚本,阻止黑客攻击sshd

    关键字 powershell Deny Hosts Fail2Ban ssh linux 近期惊闻 黑客团伙利用SSH暴力破a解,入侵远程设备 用于挖矿和DDoS攻击 疑似来自罗马…

    Linux 2023年6月14日
    076
  • rm命令弱爆了!

    大家好,我是良许。 创建、删除和修改文件是用户在 Linux 系统中执行的非常常见操作。大家都知道,在 Linux 系统里使用 rm 命令删除单个文件时,几乎一瞬间就完成了。但是如…

    Linux 2023年5月27日
    078
  • 根据温度、气压计算海拔高度

    基本概念 标准大气压:表示气压的单位,习惯上常用水银柱高度。例如,一个标准大气压等于760毫米高的水银柱的重量,它相当于一平方厘米面积上承受1.0336公斤重的大气压力。由于各国所…

    Linux 2023年6月8日
    087
  • apt-get指令关于卸载软件的各种用法

    一、 apt-get remove packagename 该命令将移除与 packagename相关联的所有二进制文件,但是不会移除与之相关联的配置文件或数据文件(configu…

    Linux 2023年5月27日
    0138
  • 双系统设置默认启动系统

    在原有windows系统下,我们装完Ubuntu系统后,会出现Ubuntu的grub引导界面(倒计时后自动进入Ubuntu),如下图所示。 假设我们需要将倒计时后默认启动的系统改为…

    Linux 2023年5月27日
    0102
  • 2021年3月-第01阶段-Linux基础-Linux系统概念-Linux命令

    Linux系统基本概念 图形界面: Ctrl+Shift +号 //调整命令终端变大 Ctrl – 号 //调整命令终端变小 命令终端: ~ 家目录:用户的私有场所,其…

    Linux 2023年6月8日
    096
  • 【C++基础】数据类型

    C++规定在创建一个变量或者产量时,必须要指定相应的数据类型,否则无法给变量分配内存空间 数据类型的存在意义:给变量分配合适的内存空间 整型 作用:整型变量表示的是整数类型的数据 …

    Linux 2023年6月13日
    089
  • 模型层

    准备阶段 django自带的sqlite3数据库,功能很少,并且针对日期类型不精确 准备步骤 数据库正向迁移命令(将类操作映射到表中) python3 manage.py make…

    Linux 2023年6月7日
    088
  • 双系统设置默认启动系统

    在原有windows系统下,我们装完Ubuntu系统后,会出现Ubuntu的grub引导界面(倒计时后自动进入Ubuntu),如下图所示。 假设我们需要将倒计时后默认启动的系统改为…

    Linux 2023年6月14日
    0127
  • linux中软件的安装方式

    linux中软件的安装方式 四种方式 ​ 源码编译安装 ​ rpm安装 ​ yum安装 解压、配置(hadoop、hive等) 1.源码编译安装 1.为了编译nginx源码 yum…

    Linux 2023年6月11日
    089
  • linux配置yum源的三种方法

    镜像下载、域名解析、时间同步请点击阿里云开源镜像站 linux配置yum源的三种方法: 1.配置网络yum源 2.通过上传镜像文件配置本地yum源 3.通过连接存储或本地镜像文件配…

    Linux 2023年5月27日
    080
  • shell bash-shell

    bash shell中的命令替换,cmd或者$(cmd)。 bash shell中的变量赋值,直接name = var; ( bash中的变量赋值不能中间有空格) 变量引用时,$n…

    Linux 2023年5月28日
    094
  • 网络通信知识地图

    知识地图是一种知识导航系统,并显示不同的知识存储之间重要的动态联系。本篇主要就是从更高的视角将之前的文章的结构思路展现出来。文章结构的思路实际上也是达到架构师程度要掌握的网络通信知…

    Linux 2023年6月14日
    099
亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球