memcached

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

安装

yum install libevent-devel*
yum install libevent-devel*
wget http://memcached.org/latest
tar zxvf memcached-1.4.29.tar.gz
./configure && make && make test && sudo make install

启动

memcached -d -m 10    -u root  -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

首先,需要安装memcache:pip3 install python-memcached

简单操作

import memcache

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

其中,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 转换成一个数字(unicode对应)
  • 将数字和主机列表长度求余数,得到一个值 N( 0 <= N < 列表长度 )
  • 在主机列表中根据 第2步得到的值为索引获取主机,例如:host_list[N]
  • 连接 将第3步中获取的主机,将 k1 = "v1" 放置在该服务器的内存中

代码怎么写呢?

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操作异常,报错:MemCached: while expecting 'STORED', got unexpected response 'NOT_STORED'

import memcache

mc=memcache.Client(['192.168.4.193:12000'],debug=True)
mc.set('foo','bar')
mc.add('cc',23) #如果已经存在'cc'的key,会报错
print(mc.get('cc'))

replace

修改某个key的值,如果key不存在,则异常,报错:MemCached: while expecting 'STORED', got unexpected response 'NOT_STORED'

import memcache

mc=memcache.Client(['192.168.4.193:12000'],debug=True)
mc.replace('cc',23)
mc.replace('alex',33) #无'alex' key,会报错

set set_multi

  • set:设置一个键值对,如果key不存在,则创建,如果key存在,则修改
  • set_multi 设置多个键值对,如果key不存在,则创建,如果key存在,则修改,注意参数为字典
import memcache

mc=memcache.Client(['192.168.4.193:12000'],debug=True)
mc.set('alex',32)
mc.set_multi({'cc':'niubi','alex':2222})

delete delete_multi

  • delete:删除指定的一个键值对,如果没有指定的key,不会报错
  • delete_multi:删除指定的多个键值对,注意参数为列表
import memcache

mc=memcache.Client(['192.168.4.193:12000'],debug=True)
mc.delete('aaa')
mc.delete('alex')
print(mc.get('alex'))
mc.delete_multi(['cc','alex2'])
print(mc.get('alex2'),mc.get('cc'))

get get_multi

  • get:获取一个键值对
  • get_multi:获取多个键值对,参数为列表,返回值为字典类型
import memcache

mc=memcache.Client(['192.168.4.193:12000'],debug=True)
mc.set('cc','ccccc')
print(mc.get('cc'))
print(mc.get_multi(['cc','laex','2222']))

out:

ccccc
{'cc': 'ccccc'}

append prepend

  • append:修改指定key的值,在值的后面追加内容,无指定key会报异常
  • prepend:修改指定key的值,在值的前面插入内容
import memcache

mc=memcache.Client(['192.168.4.193:12000'],debug=True)
mc.append('cc','dd')
mc.append('ds','dsdsds') #不存在ds,会报异常
print(mc.get('ds'))
mc.prepend('cc','aa')
print(mc.get('cc'))

decr incr

  • incr:自增,将Memcached中的某一个值增加N,(N默认为1),如果值非数字,会报错
  • decr:自减,将Memcached中的某一个值减少N,(N默认为1),如果值非数字,会报错
import memcache

mc=memcache.Client(['192.168.4.193:12000'],debug=True)
mc.set('cc',23)
mc.incr('cc')
print(mc.get('cc'))
mc.decr('cc',3)
print(mc.get('cc'))

out:

24
21

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来操作以上过程,那么程序就会如上述所示情况!

一句话总结

其实就是为了避免在生产环境中产生脏数据,使用gets和cas

import memcache

mc=memcache.Client(['192.168.4.193:12000'],debug=True)
mc.set('count',999)
print(mc.gets('count'))
# 如果有人在gets之后和cas之前修改了product_count,那么,下面的设置将会执行失败,抛出异常,从而避免非正常数据的产生
mc.cas('count',981)
#cas也能创建一个不存在key的键值对
mc.cas('we',90)
print(mc.gets('we'))

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

memcache是否已经过时?

转自:开源中国社区

源地址,戳我戳我

这两年Redis火得可以,Redis也常常被当作Memcached的挑战者被提到桌面上来。关于Redis与Memcached的比较更是比比皆是。然而,Redis真的在功能、性能以及内存使用效率上都超越了Memcached吗?

下面内容来自Redis作者在stackoverflow上的一个回答,对应的问题是《Is memcached a dinosaur in comparison to Redis?》(相比Redis,Memcached真的过时了吗?)

You should not care too much about performances. Redis is faster per core with small values, but memcached is able to use multiple cores with a single executable and TCP port without help from the client. Also memcached is faster with big values in the order of 100k. Redis recently improved a lot about big values (unstable branch) but still memcached is faster in this use case. The point here is: nor one or the other will likely going to be your bottleneck for the query-per-second they can deliver.
没有必要过多的关心性能,因为二者的性能都已经足够高了。由于Redis只使用单核,而Memcached可以使用多核,所以在比较上,平均每一 个核上Redis在存储小数据时比Memcached性能更高。而在100k以上的数据中,Memcached性能要高于Redis,虽然Redis最近 也在存储大数据的性能上进行优化,但是比起Memcached,还是稍有逊色。说了这么多,结论是,无论你使用哪一个,每秒处理请求的次数都不会成为瓶 颈。(比如瓶颈可能会在网卡)
You should care about memory usage. For simple key-value pairs memcached is more memory efficient. If you use Redis hashes, Redis is more memory efficient. Depends on the use case.
如果要说内存使用效率,使用简单的key-value存储的话,Memcached的内存利用率更高,而如果Redis采用hash结构来做key-value存储,由于其组合式的压缩,其内存利用率会高于Memcached。当然,这和你的应用场景和数据特性有关。
You should care about persistence and replication, two features only available in Redis. Even if your goal is to build a cache it helps that after an upgrade or a reboot your data are still there.
如果你对数据持久化和数据同步有所要求,那么推荐你选择Redis,因为这两个特性Memcached都不具备。即使你只是希望在升级或者重启系统后缓存数据不会丢失,选择Redis也是明智的。
You should care about the kind of operations you need. In Redis there are a lot of complex operations, even just considering the caching use case, you often can do a lot more in a single operation, without requiring data to be processed client side (a lot of I/O is sometimes needed). This operations are often as fast as plain GET and SET. So if you don’t need just GEt/SET but more complex things Redis can help a lot (think at timeline caching).
当然,最后还得说到你的具体应用需求。Redis相比Memcached来说,拥有更多的数据结构和并支持更丰富的数据操作,通常在 Memcached里,你需要将数据拿到客户端来进行类似的修改再set回去。这大大增加了网络IO的次数和数据体积。在Redis中,这些复杂的操作通 常和一般的GET/SET一样高效。所以,如果你需要缓存能够支持更复杂的结构和操作,那么Redis会是不错的选择。

Python操作memecache的更多相关文章

  1. Python之路:Python操作 RabbitMQ、Redis、Memcache、SQLAlchemy

    Memcached Memcached 是一个高性能的分布式内存对象缓存系统,用于动态Web应用以减轻数据库负载.它通过在内存中缓存数据和对象来减少读取数据库的次数,从而提高动态.数据库驱动网站的速度 ...

  2. 【转】Python操作 RabbitMQ、Redis、Memcache、SQLAlchemy

    Memcached Memcached 是一个高性能的分布式内存对象缓存系统,用于动态Web应用以减轻数据库负载.它通过在内存中缓存数据和对象来减少读取数据库的次数,从而提高动态.数据库驱动网站的速度 ...

  3. python操作RabbitMQ、Redis、Memcache、SQLAlchemy

    Memcached Memcached 是一个高性能的分布式内存对象缓存系统,用于动态Web应用以减轻数据库负载.它通过在内存中缓存数据和对象来减少读取数据库的次数,从而提高动态.数据库驱动网站的速度 ...

  4. python操作nosql数据库之memcache

    一.memcache的安装 1.memcache简介 Memcached是一个高性能的分布式内存对象缓存系统,用于动态Web应用以减轻数据库负载.它通过在内存中缓存数据和对象减少读取数据库的次数,从而 ...

  5. Python操作Redis(一)

    redis是一个key-value存储系统.和Memcached类似,它支持存储的value类型相对更多,包括string(字符串).list(链表).set(集合).zset(sorted set ...

  6. Python(九) Python 操作 MySQL 之 pysql 与 SQLAchemy

    本文针对 Python 操作 MySQL 主要使用的两种方式讲解: 原生模块 pymsql ORM框架 SQLAchemy 本章内容: pymsql 执行 sql 增\删\改\查 语句 pymsql ...

  7. Python 【第六章】:Python操作 RabbitMQ、Redis、Memcache、SQLAlchemy

    Memcached Memcached 是一个高性能的分布式内存对象缓存系统,用于动态Web应用以减轻数据库负载.它通过在内存中缓存数据和对象来减少读取数据库的次数,从而提高动态.数据库驱动网站的速度 ...

  8. 练习:python 操作Mysql 实现登录验证 用户权限管理

    python 操作Mysql 实现登录验证 用户权限管理

  9. Python操作MySQL

    本篇对于Python操作MySQL主要使用两种方式: 原生模块 pymsql ORM框架 SQLAchemy pymsql pymsql是Python中操作MySQL的模块,其使用方法和MySQLdb ...

随机推荐

  1. 6.Hbase 原理

    2 HBase体系结构 2.1 设计思路 HBase是一个分布式的数据库,使用Zookeeper管理集群,使用HDFS作为底层存储.在架构层面上由HMaster(Zookeeper选举产生的Leade ...

  2. NLP学习(2)----文本分类模型

    实战:https://github.com/jiangxinyang227/NLP-Project 一.简介: 1.传统的文本分类方法:[人工特征工程+浅层分类模型] (1)文本预处理: ①(中文) ...

  3. BZOJ 1458 / Luogu P4311 士兵占领 (上下界最小流 / 直接最大流)

    做法1:上下界最小流 先来一发上下界最小流,思路比较暴力,就是把行和列看作n+mn+mn+m个点,(i,j)(i,j)(i,j)如果能占领就从第iii行向第jjj列连一条边,上界为1下界为0;然后从s ...

  4. [HTML5] Lazyload below the fold images and iframes with native browser lazy-loading

    In this lesson, you'll learn how to use the loading="lazy" attribute available on images a ...

  5. QPS 和 TPS

  6. 为什么margin:0 auto不能用于inline-block元素

    前言:今天一个实习生问我,为什么他对图片使用了margin:0 auto,但图片却没有居中,我让他换成对父元素使用text-align:center即可.为什么margin:0 auto对图片不起作用 ...

  7. Codeforces Round #521 (Div.3)题解

    A过水,不讲 题解 CF1077B [Disturbed People] 这题就是个显而易见的贪心可是我考场上差点没想出来 显然把一户被打扰的人家的右边人家的灯关掉肯定比把左边的灯关掉 从左到右扫一遍 ...

  8. crm-权限管理

    1 用户登录 设置session 将权限存放在session中 2 设置中间件,进行拦截 0 添加白名单,判断是否在白名单上 1 判断是否登录 2 权限过滤

  9. About Grisha N. ( URAL - 2012 )

    Problem Grisha N. told his two teammates that he was going to solve all given problems at the subreg ...

  10. gopub自动化发布平台安装

    1.软件配置 centos7 mysql5.7.26 gopub1.1.3 2.硬件配置 4核8G aws rds aws 3.数据库配置 #这个不执行,执行下面一句 --CREATE DATABAS ...