二十、python访问memcached
发布日期:2021-10-31 07:31:28 浏览次数:13 分类:技术文章

本文共 3639 字,大约阅读时间需要 12 分钟。

memcached介绍

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

memcached在实现分布式群集部署时,memcached服务之间是不能进行通讯的,分布式也是通过客户端的算法把数据保存在不同的memcached中。magent是一款开源的代理服务软件,我们可以通过它来实现缓存数据的同步。magent还可以使用keepalived来实现高可用。

memcached安装

安装libevent

Libevent 是一个异步事件处理软件函式库,以 BSD 许可证释出。Memcached 依赖 Libevent,因此必须先安装 Libevent。

yum install libevent-devel

安装memcached

cd /usr/local/srcwget http://memcached.org/latesttar zxf memcached-1.5.7.tar.gzmv memcached-1.5.7 memcachedcd memcached/./configure && make && make install

启动

memcached -d -u root

启动参数说明

memcached -d -m 10 -u root -l 127.0.0.1 -p 12000 -c 256 -P /tmp/memcache/logs/memcache.pid-p 指定端口号(默认11211)-m 指定最大使用内存大小(默认64MB)-t 线程数(默认4)-l 连接的IP地址, 默认是本机-d 以后台守护进程的方式启动-c 最大同时连接数,默认是1024-P 制定memecache的pid文件-h 打印帮助信息

python访问memcached

python访问memcached需要安装python-memcached模块。

pip install python-memcached

操作实例

import memcachemem = memcache.Client(["118.24.18.158:11211"])mem.set("db", "oracle")print(mem.get("db"))    #输出结果:oracle

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

主机IP        权重1.1.1.1        11.1.1.2        21.1.1.3        1

那么内存中主机列表为:host_list = [“1.1.1.1”, “1.1.1.2”,”1.1.1.2”,”1.1.1.3”,]

用户如果要在内存中创建一个键值对(如:k1 = “value1”),那么要执行以下步骤:
根据算法将k1转换成一个数字
将数字和主机列表长度求余数,得到一个值N(0 <= N < 长度)
在主机列表中根据第二步得到的值为索引获取主机,例如: host_list[N]
连接将第三步中获取的主机,将k1 = “value1” 放置在该服务器的内存中
代码如下:

#!/usr/bin/env python3#coding:utf8import memcachemc = memcache.Client([('1.1.1.1:11211', 1), ('1.1.1.2:11211', 2),('1.1.1.3:11211',1)])mc.set('k1','value1')ret = mc.get('k1')print (ret)

memcached常用操作

set(key, val)

在memcache中设置key的值为val。若key不存在则创建,否则修改。
get(key)
获取memcache中key对应的值或者None。
set_multi(mapping)
一次设置多个key/value对。以列表方式传入。若key不存在则创建,否则修改。
get_multi(keys)
一次获取多个keys

mem.set_multi({
"db1": "oracle", "db2": "mysql"})mem.set("db3", "memcache")print(mem.get("db1")) #输出结果:oracleprint(mem.get_multi(["db2", "db3"])) #输出结果:{
'db2': 'mysql', 'db3': 'memcache'}

add(key, val)

在memcache中添加新的键值对。若已存在则返回False。

print(mem.add("db", "memcache"))     #输出结果:Trueprint(mem.get("db"))     #输出结果:memcacheprint(mem.add("db", "memcache"))     #输出结果:False

replace(key, val)

修改key的值为val,若不存在则返回False。

mem.add("db", "memcache")print(mem.replace("db", "redis"))    #输出结果:Trueprint(mem.get("db"))    #输出结果:redisprint(mem.replace("db1", "redis"))    #输出结果:False

delete(key)

删除一个指定的key/value对。

delete_multi(keys)

删除多个指定的key/value对。

mem.set_multi({
"db1": "oracle", "db2": "mysql", "db3": "memcache"})mem.delete("db1")mem.delete_multi(["db2", "db3"])print(mem.get_multi(["db1", "db2", "db3"])) #输出结果:{}

append(key, val)

在指定key对应的value后面追加内容。

prepend(key, val)

在指定key对应的额value前面追加内容。
stats
查看历史操作

mem.set("db", "oracle")print(mem.get("db"))    #输出结果:oraclemem.append("db", " or mysql")print(mem.get("db"))    #输出结果:oracle or mysqlmem.prepend("db", "redis or ")print(mem.get("db"))    #输出结果:redis or oracle or mysqlprint(mem.stats)    #输出结果:{
'set': 1, 'get': 3, 'append': 1, 'prepend': 1}

gets和cas

使用缓存系统共享数据资源就必然绕不开数据争夺和脏数据(数据混乱)的问题。
假设商城某件商品的剩余个数保存在memcache中,product_count = 900,
A用户刷新页面从memecache中读取到product_count = 900,
B用户刷新页面从memecache中读取到product_count = 900,
A,B用户均购买商品,并修改product_count的值。
A修改后,product_count = 899;
B修改后,product_count = 899;
然而正确数字应该是898,数据就混乱了。
如果想要避免这种情况的发生,则可以使用gets和cas。

mem = memcache.Client(["118.24.18.158:11211"])mem.set("count", "100")print(mem.get("count"))    #输出结果:100print(mem.cas("count", "99"))    #输出结果:Trueprint(mem.gets("count"))    #输出结果:99

gets和cas一起使用,cas是check and set操作。它仅当当前客户端最后一次取值后,该key对应的值没有被其他客户端修改的情况下,才能够将值写入。

转载地址:https://blog.csdn.net/weixin_39934221/article/details/80387942 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:二十一、python多进程
下一篇:十九、python操作redis

发表评论

最新留言

不错!
[***.144.177.141]2024年03月29日 07时06分21秒

关于作者

    喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!

推荐文章

【Leetcode刷题篇】leetcode88 合并两个有序数组 2019-04-26
【Leetcode刷题篇】剑指offer51 数组中的逆序对 2019-04-26
【Leetcode刷题篇】剑指offer55-平衡二叉树 2019-04-26
【Leetcode刷题篇】leetcode98 判断一棵树是否为二叉搜索树 2019-04-26
Java中arraylist和数组的相互转换 2019-04-26
【Leetcode刷题篇 】leetcode147 对链表进行插入排序 2019-04-26
【Leetcode刷题篇】leetcode148 排序链表 2019-04-26
【面试篇】Java中String、StringBuilder与StringBuffer的区别? 2019-04-26
【面试篇】Java对象的hashCode()相同,equals()一定为true吗? 2019-04-26
【面试篇】Java中static和final关键字的作用是什么? 2019-04-26
【面试篇】Java中接口和抽象类的区别是什么? 2019-04-26
【Java网络编程与IO流】Java中IO流分为几种?字符流、字节流、缓冲流、输入流、输出流、节点流、处理流 2019-04-26
【Java网络编程与IO流】Java中BIO、NIO、AIO的区别是什么? 2019-04-26
【Leetcode刷题篇】leetcode136 只出现一次的数字 2019-04-26
spring boot整合thymeleaf,支持JSP和HTML页面开发 2019-04-26
【Java网络编程与IO流】Spring boot整合SSE实现服务器实时推送流信息 2019-04-26
【Java网络编程与IO流】SpringBoot + WebSocket + Netty实现实时的服务器消息推送 2019-04-26
【Leetcode刷题篇】leetcode141 环形链表II 2019-04-26
【Leetcode刷题篇】leetcode160 相交链表 2019-04-26
【Leetcode刷题篇】leetcode169 多数元素 2019-04-26