memcached
Memcached 是一个高性能的分布式内存对象缓存系统,用于动态Web应用以减轻数据库负载。它通过在内存中缓存数据和对象来减少读取数据库的次数,从而提高动态、数据库驱动网站的速度。Memcached基于一个存储键/值对的hashmap。其守护进程(daemon )是用C写的,但是客户端可以用任何语言来编写,并通过memcached协议与守护进程通信。
Memcached安装和基本使用
Memcached安装:
1
2
3
4
5
6
7
8
|
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
1
2
3
4
5
6
7
8
9
10
|
memcached - 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命令
1
2
3
|
存储命令: set / add / replace / append / prepend / cas 获取命令: get / gets 其他命令: delete / stats.. |
Python操作Memcached
安装API
1
2
|
python操作Memcached使用Python - memcached模块 下载安装:https: / / pypi.python.org / pypi / python - memcached |
1、第一次操作
1
2
3
4
5
6
|
import memcache mc = memcache.Client([ '10.211.55.4:12000' ], debug = True ) mc. set ( "foo" , "bar" ) ret = mc.get( 'foo' ) print ret |
Ps:debug = True 表示运行出现错误时,现实错误信息,上线后移除该参数。
2、天生支持集群
python-memcached模块原生支持集群操作,其原理是在内存维护一个主机列表,且集群中主机的权重值和主机在列表中重复出现的次数成正比
1
2
3
4
5
6
7
|
主机 权重 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" 放置在该服务器的内存中
代码实现如下:
1
2
3
|
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' ) |
3、add
添加一条键值对,如果已经存在的 key,重复执行add操作异常
1
2
3
4
5
6
7
|
#!/usr/bin/env python # -*- coding:utf-8 -*- import memcache mc = memcache.Client([ '10.211.55.4:12000' ], debug = True ) mc.add( 'k1' , 'v1' ) # mc.add('k1', 'v2') # 报错,对已经存在的key重复添加,失败!!! |
4、replace
replace 修改某个key的值,如果key不存在,则异常
1
2
3
4
5
6
7
|
#!/usr/bin/env python # -*- coding:utf-8 -*- import memcache mc = memcache.Client([ '10.211.55.4:12000' ], debug = True ) # 如果memcache中存在kkkk,则替换成功,否则一场 mc.replace( 'kkkk' , '999' ) |
5、set 和 set_multi
set 设置一个键值对,如果key不存在,则创建,如果key存在,则修改
set_multi 设置多个键值对,如果key不存在,则创建,如果key存在,则修改
1
2
3
4
5
6
7
8
9
|
#!/usr/bin/env python # -*- coding:utf-8 -*- import memcache mc = memcache.Client([ '10.211.55.4:12000' ], debug = True ) mc. set ( 'key0' , 'wupeiqi' ) mc.set_multi({ 'key1' : 'val1' , 'key2' : 'val2' }) |
6、delete 和 delete_multi
delete 在Memcached中删除指定的一个键值对
delete_multi 在Memcached中删除指定的多个键值对
1
2
3
4
5
6
7
8
|
#!/usr/bin/env python # -*- coding:utf-8 -*- import memcache mc = memcache.Client([ '10.211.55.4:12000' ], debug = True ) mc.delete( 'key0' ) mc.delete_multi([ 'key1' , 'key2' ]) |
7、get 和 get_multi
get 获取一个键值对
get_multi 获取多一个键值对
1
2
3
4
5
6
7
8
|
#!/usr/bin/env python # -*- coding:utf-8 -*- import memcache mc = memcache.Client([ '10.211.55.4:12000' ], debug = True ) val = mc.get( 'key0' ) item_dict = mc.get_multi([ "key1" , "key2" , "key3" ]) |
8、append 和 prepend
append 修改指定key的值,在该值 后面 追加内容
prepend 修改指定key的值,在该值 前面 插入内容
1
2
3
4
5
6
7
8
9
10
11
12
|
#!/usr/bin/env python # -*- coding:utf-8 -*- import memcache mc = memcache.Client([ '10.211.55.4:12000' ], debug = True ) # k1 = "v1" mc.append( 'k1' , 'after' ) # k1 = "v1after" mc.prepend( 'k1' , 'before' ) # k1 = "beforev1after" |
9、decr 和 incr
incr 自增,将Memcached中的某一个值增加 N ( N默认为1 )
decr 自减,将Memcached中的某一个值减少 N ( N默认为1 )
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
#!/usr/bin/env python # -*- coding:utf-8 -*- import memcache mc = memcache.Client([ '10.211.55.4:12000' ], 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 |
10、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 即可,如:
1
2
3
4
5
6
7
8
9
|
#!/usr/bin/env python # -*- coding:utf-8 -*- import memcache mc = memcache.Client([ '10.211.55.4:12000' ], debug = True , cache_cas = True ) v = mc.gets( 'product_count' ) # ... # 如果有人在gets之后和cas之前修改了product_count,那么,下面的设置将会执行失败,剖出异常,从而避免非正常数据的产生 mc.cas( 'product_count' , "899" ) |
Ps:本质上每次执行gets时,会从memcache中获取一个自增的数字,通过cas去修改gets的值时,会携带之前获取的自增值和memcache中的自增值进行比较,如果相等,则可以提交,如果不想等,那表示在gets和cas执行之间,又有其他人执行了gets(获取了缓冲的指定值), 如此一来有可能出现非正常数据,则不允许修改。
memcached的更多相关文章
- 支持 .NET Core 的 Memcached 客户端 EnyimMemcachedCore
1. 介绍 EnyimMemcachedCore 是一个支持 .NET Core 的 Memcached 客户端,是从 EnyimMemcached 迁移至 .NET Core的,源代码托管在 Git ...
- Key/Value之王Memcached初探:二、Memcached在.Net中的基本操作
一.Memcached ClientLib For .Net 首先,不得不说,许多语言都实现了连接Memcached的客户端,其中以Perl.PHP为主. 仅仅memcached网站上列出的语言就有: ...
- ASP.Net MVC4+Memcached+CodeFirst实现分布式缓存
ASP.Net MVC4+Memcached+CodeFirst实现分布式缓存 part 1:给我点时间,允许我感慨一下2016年 正好有时间,总结一下最近使用的一些技术,也算是为2016年画上一个完 ...
- 缓存、队列(Memcached、redis、RabbitMQ)
本章内容: Memcached 简介.安装.使用 Python 操作 Memcached 天生支持集群 redis 简介.安装.使用.实例 Python 操作 Redis String.Hash.Li ...
- 企业做数据缓存是使用Memcached还是选Redis?
企业是使用Memcached还是选Redis? 在构建一款现代且由数据库驱动的Web应用程序并希望使其拥有更为出色的性能表现时,这个问题总会时不时出现.并给每一位开发人员带来困扰.在考虑对应用程序的性 ...
- NoSql1 在Linux(CentOS)上安装memcached及使用
前言: 今天是初五,生活基本要从过年的节奏中回归到正常的生活了,所以想想也该想想与工作有关的事情了.我之前在工作中会经常使用memcached和redis,但是自己一直没有时间系统的好好看 ...
- Memcached简介
在Web服务开发中,服务端缓存是服务实现中所常常采用的一种提高服务性能的方法.其通过记录某部分计算结果来尝试避免再次执行得到该结果所需要的复杂计算,从而提高了服务的运行效率. 除了能够提高服务的运行效 ...
- Linux 服务器 安装 memcached
linux centos 一.memcached的安装 1.下载 memcached-1.4.33.tar.gz.libevent-2.0.22-stable.tar.gz 安装 memcached ...
- Memcached和Redis比较
一.存储 Memcached基本只支持简单的key-value存储方式.Redis除key-value之外,还支持list,set,sorted set,hash等数据结构:Redis支持数据的备份, ...
- 搭建LNAMP环境(七)- PHP7源码安装Memcached和Memcache拓展
上一篇:搭建LNAMP环境(六)- PHP7源码安装MongoDB和MongoDB拓展 一.安装Memcached 1.yum安装libevent事件触发管理器 yum -y install libe ...
随机推荐
- iOS开发之巧用Block和代理方法结合来传值
好久没写技术博客了,因为996的工作周期已经持续好几个月了.每天晚上回家都没有太多精力学习很多其他的东西,而且很多时候是接着完善工作的项目的模块开发.所以博客停歇了这么久,更新率也低了不少,今天补充一 ...
- 使用DOTNETZIP过滤并压缩相对目录
业务要求: 压缩某个文件夹及其子目录 压缩时只压缩指定的文件类型,如cshtml 压缩后保持相对目录 找了很久,没有直接的DEMO,最后尝试通过以下代码完成 示例演示了只压缩cshtml和js,同 ...
- 2015-SH项目总结
2015年,加入现在的公司(外包公司,名字就不说了),做SH项目(化名),在这个月(2016.01)结束了. 虽然公司也有做项目总结,不过我还是自己也总结一次. 项目概况: 这是个为一间私人会所提供全 ...
- yii2 左侧菜单子级无法高亮的问题
作者:白狼 出处:http://www.manks.top/question/20160508000001.html 本文版权归作者,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出 ...
- 如何转换SQL Server 2008数据库到SQL Server 2005
背景介绍: 公司一套系统使用的是SQL SERVER 2008数据库,突然一天收到邮件,需要将这套系统部署到各个不同地方(海外)的工厂,需要在各个工厂部署该数据库,等我将准备工作做好,整理文档 ...
- [解决]Mercurial HTTP Error 500: Access is denied on 00changelog.i
总之,用户对仓库目录要有写权限 00changelog, access is denied, hg, http error 500, mercurial, permissions, push Merc ...
- Node Pm2 配置
系统环境:Centos7 第一步安装NodeJS 建议采用稳定编译过的版本,source code稍麻烦,编译过的直接可用,安装超级简单 下载完成后安装成功 node -v 显示版本号 npm -v ...
- TCP通信丢包原因总结
今天在公司问老大,公司的项目底层,是使用的TCP,因为可靠,自动断线重连,在底层都实现了,但是我记得TCP也会有掉包的问题,所以这文章就诞生了——关于TCP掉包的问题,TCP是基于不可靠的网络实现可靠 ...
- Postgresql扩展及UUID
切换数据库 \connect $DBNAME 查看Postgresql的可用扩展 SELECT * FROM pg_available_extensions; 安装所需扩展 CREATE EXTENS ...
- netty3升netty4一失眼成千古恨
老项目是netty3的,本来想直接改到netty5,但是netty5居然是只支持jdk1.7,很奇怪jdk1.6和jdk1.8都不行..为了兼容jdk1.6加上netty4本来和netty5就差别不大 ...