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/684744/

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

(0)

大家都在看

  • 有意义的学习,都要先回答三个问题

    我们都知道, 在现代经济中, 我们不能停止学习。但如何保持自我教育是一个复杂的问题。 获得一个正式学位,比如 MBA 或博士学位, 是否值得? 你是否应该采取更有针对性的方法, 参…

    技术杂谈 2023年5月31日
    078
  • 很详细的FFT(快速傅里叶变换)概念与实现

    FFT 首先要说明一个误区,很多人认为FFT只是用来处理多项式乘的,其实FFT是用来实现多项式的系数表示法和点值表示法的快速转换的,所以FFT的用处远不止多项式乘。 FFT的前置知…

    技术杂谈 2023年6月21日
    066
  • Android:Jetpack之视图绑定——ViewBinding

    1.Jetpack简介 手机厂商还没卷完Android 12, Android 13就悄然声息地来了,距离Google 2008年9月22日发布Android 1.0,已过去13个…

    技术杂谈 2023年7月10日
    074
  • Linux 快速查找并结束僵尸进程

    Linux SSH 连接后显示: There is 1 zombie process. 说明当前正在运行的系统当中存在1个僵尸进程正在无意义消耗资源。 ==============…

    技术杂谈 2023年6月21日
    078
  • 互联网校招指北

    这篇文章写着写着,突然觉得《紧急救援》中有一句台词很对: “不是幸运给你机会,而是因为够坚持,才有了幸运的机会” 共勉~ 时间跨度 一年共两次校招季,2 月…

    技术杂谈 2023年7月25日
    065
  • JBoss4.2.2配置及优化

    本文是在[url=http://solarisxb.cublog.cn]SOLARIS小兵[/url]的[url=http://blog.chinaunix.net/u/504/s…

    技术杂谈 2023年5月30日
    062
  • 设计模式-六大设计原则

    六大设计原则 单一职责原则 我们分别看两个案例,一个是遵守单一职责原则,另一个是违背。 违背的案例 public class Computer { void calc() { Sy…

    技术杂谈 2023年7月11日
    080
  • Docker概述(一)

    Docker概述(一) 顺便介绍下:我们是一家致力于智能语音交互的AI公司,我们提供了语音识别、语音合成、声纹识别、声音复刻、声音转换等技术产品供小伙伴们测试调用,感兴趣的,第三部…

    技术杂谈 2023年7月24日
    088
  • [学习笔记]Java枚举

    在Java中,枚举是一种特殊的类,一般用于表示一组常量; 定义枚举时使用 enum关键字,各个常量使用逗号分隔; 也可以在类的内部定义枚举: 每个枚举都以内部类的形式实现,且所有的…

    技术杂谈 2023年7月24日
    052
  • 【JavaWeb-jQuery】笔记(2)- jQuery 函数精讲

    第一组函数: 1、val: 操作 DOM 数组中的对象的 value 属性 $(选择器).val();//&amp…

    技术杂谈 2023年7月10日
    051
  • c#使用selenium过滑动验证码

    滑动验证码如下: 1、vs引入以下三个包(.net core 3.1): 2、c#引用: private void SeleniumVertifyCode(Uri uri) { v…

    技术杂谈 2023年5月30日
    082
  • SSM框架整合

    SSM框架整合 一、idea创建项目 1.创建普通的maven项目然后next 建完之后的第一件大事就是项目改成UTF-8编码: 2.maven导入相关的pom依赖 pom.xml…

    技术杂谈 2023年7月11日
    068
  • 京东主站黄金流程——统一支付能力升级

    背景介绍 京东APP购物的黄金流程包括搜索、商品详情、购物车、结算、订单、支付等。支付是黄金流程重要的收尾环节,也是交易链路的最后一道防线。 老收银台在过去数年间,在多复杂类型、高…

    技术杂谈 2023年5月31日
    091
  • ant design mini

    外包项目可以找我,前端后端一锅端,作者:漫思,转载请注明原文链接:https://www.cnblogs.com/sexintercourse/p/16551655.html 如有…

    技术杂谈 2023年6月1日
    087
  • inotify-tools使用方法介绍

    inotify-tools 是为linux下inotify文件监控工具提供的一套c的开发接口库函数,同时还提供了一系列的命令行工具,这些工具可以用来监控文件系统的事件。 inoti…

    技术杂谈 2023年6月1日
    091
  • 剑指offer计划24( 数学中等)—java

    1.1、题目1 剑指 Offer 14- I. 剪绳子 1.2、解法 这几天的题都不在行。。。。 1.3、代码 class Solution { public int cuttin…

    技术杂谈 2023年7月25日
    060
亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球