Redis, Memcache 基本使用

Redis, Memcache

Memcache

MemCache是一个自由、源码开放、高性能、分布式的内存对象缓存系统,用于动态Web应用以减轻数据库的负载。它通过在内存中缓存数据和对象来减少读取数据库的次数,从而提高了网站访问的速度。

安装

https://github.com/memcached/memcached/wiki/Install

启动服务

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文件

测试时可以关闭防火墙,否则客户端无法访问:systemctl stop firewalld.service

python中操作MemCache

安装API
pip install python-memcached -i https://pypi.douban.com/simple
操作测试

这里在Django项目中测试

from django.conf.urls import url
from django.shortcuts import HttpResponse
import memcache


def test(request):
    mc = memcache.Client(['192.168.14.16:12000'], debug=True)
    mc.set('name', 'Lena', time=5)  # 超时5秒
    name = mc.get('name')
    return HttpResponse(name)

urlpatterns = [
    url(r'^test/', test),
]
分布式缓存

配置多个服务端,并设置权重,权重越高,命中几率越高。

 mc = memcache.Client([('192.168.14.16:12000', 1), ('192.168.14.17:12000', 2), ('192.168.14.18:12000', 3)], debug=True)  # 分别设置1,2,3权重

Memcache的分布式是由客户端程序的一致性哈希实现的,更多参考:http://www.csdn.net/article/2016-03-16/2826609

MemCache常用方法

注意:

  • MemCache中存的值只支持字符串和数字
  • 超时设置的时间单位是秒,超时后取出结果是None
命 令作 用
get返回Key对应的Value值:mc.get(key)
add添加一个Key值,没有则添加,有则报错:mc.add(key, val, time=10) 添加键值,并设置超时10秒
set设置一个Key值,没有就增加,有就覆盖:mc.set(key, val, time=10)
replace按照相应的Key值替换数据,如果Key值不存在则会操作失败:mc.replace(key, val)
delete删除一个键值对:mc.delete(key)
stats返回MemCache通用统计信息
flush_all清空所有键值,但不会删除items,所以此时MemCache依旧占用内存:mc.flush_all()

其它方法

set_multi 设置多个键值对
mc.set_multi({k1: v1, k2: v2})
del_multi删除多个键值对
mc.set_multi([k1, k2])
incr & decr

将key对应的值增加/减小

mc.set('a', 10)
mc.incr('a', 10)  # 'a' = 20
mc.decr('a', 5)  # 'a' = 15
append & prepend

在指定key值后面/前面追加

mc.set('name', 'Lena')  # 'name'= 'Lena'
mc.append('name', 'Ayhan')  # 'name' = 'LenaAyhan'
cas & gets

为了避免两个请求同时修改某个值,造成数据异常。getscas需要配合使用。

通过gets获取值的时候(假设是val),会多返回一个数字,就叫做cas_id吧,当val改变时(比如期间有另一个请求修改了val),这个cas_id也会变。当执行cas(check and set)重新设置值时,将检查cas_id是否和gets取出值时的cas_id匹配,如果匹配则修改,如果不匹配,表示期间有其它请求修改了val,则无法修改.

val = mc.gets(key)  
# ...
# 如果在gets和cas之间有请求修改了key的值,那么,下面的cas将会检查到cas_id变了,抛出异常,避免修改造成数据异常
mc.cas(key, new_val)

Redis

同MemCache一样,Redis也是在服务器内存中保存的非关系型数据库(缓存),但是二者还是有些区别:

如果你对数据持久化和数据同步有所要求,那么推荐你选择Redis,因为这两个特性Memcached都不具备。即使你只是希望在升级或者重启系统后缓存数据不会丢失,选择Redis也是明智的。

Redis相比Memcached来说,拥有更多的数据结构和并支持更丰富的数据操作。

Redis不仅可以支持分布式,还具有高可用的特点:可以将数据定时刷入硬盘,解决了内存断电易失的问题。并且它支持更多的的数据类型:字符串,数字,列表,集合,字典,有序集合。

在python中使用Redis

centos服务端安装

yum install redis

如果安装不上,先安装epel仓库yum install epel-release,再执行上述安装命令。

启动服务端:

systemctl start redis

配置:

vim/etc/redis.conf

# bind 127.0.0.1  这一行要注释掉,否则客户端连接不上
equirepass 123  # 设置密码

客户端安装:

pip install redis

连接

方式一
import redis
conn = redis.Redis(host=, port=, password='123')

不推荐,每次都会重新连接,创建新的对象。

方式二 推荐

推荐用连接池:

pool = redis.ConnectionPool(host=xx, port=xx, password='123')
conn = redis.Redis(connection_pool = pool)
进阶:单例模式

这里的host, port, password可以写到配置文件中。

import redis


class Singleton(object):
    def __new__(cls, *args, **kwargs):
        # 如果当前类没有_instance属性,那么就调用父类的__new__方法实例化对象,新增_instance属性并赋值
        if not hasattr(cls, "_instance"):
            cls._instance = super(Singleton, cls).__new__(cls)
        return cls._instance


class SingleRedis(Singleton):
    def __init__(self, host='192.168.14.16', port=6379, password=123):
        pool = redis.ConnectionPool(host=host, port=port, password=password)
        self.conn = redis.Redis(connection_pool=pool)

# 使用
redis = SingleRedis()
redis.conn.set(key, val)

字符常用操作

conn.set(name, value, ex=None, px=None, nx=False, xx=False)

为name设置value(字符/数字类型);

ex/px: 过期时间(秒/毫秒);

nx: 如果为True,那么只有当name对应的value不存在时,该操作才能成功(即如果name在Redis中已经有value,将不会设置新的value,保留原来的值);默认False,无论如何设置新值。

xx: 如果为True,那么只有当name对应的value已经存在时,该操作才能成功(即只能更新已存在的name)。

conn.mset(*args, **kwargs)

批量设置值

conn.mset(k1=v1, k2=v2)
# 或者
conn.mset({k1: v1, k2: v2})
conn.get(name)

返回name对应的value,如果不存在返回None

conn.get(keys, *args)

批量获取值

conn.mget(k1, k2)
# 或者
conn.mget([k1, k2])
conn.incr/decr(name, amount=1)

将name对应的value增加/减少amount,如果name不存在,将创建并初始化值为amount

列表常用操作

conn.lpush(name, *values)

往name对应的列表中添加元素(依次添加到最左边)

redis.conn.lpush('fruits', 'banana', 'orange')
# fruits: ['orange', 'banana']
conn.rpush(name, *values)

往k对应的列表中添加元素(从右边添加)

conn.llen(name)

name对应列表的长度

conn.lpop(name)

name对应列表的左边弹出一个值并返回

conn.rpop(name)

name对应列表的右边弹出一个值并返回

字典常用操作

conn.hset(name, key, value)

设置字典 name: {key: value};

conn.hset(name, key2, value2) name: {key: value, key2: value2} 字典

注意如果value是字典或其它格式,需要先序列化为字符串

conn.hget(name, key)

获取name对应字典中key对应的value

conn.hdel(name, key)

删除name对应字典中的key

集合操作

将前缀s改为z,即可变为有序集合

conn.sadd(name, *values)

往name集合中添加元素

conn.scard(name)

返回name集合中元素的个数

conn.smembers(name)

获取name集合中的所有元素

conn.srem(name, *values)

删除name集合中某些元素

其它操作

delete(*names)

删除指定的keys

exists(name)

判断name是否存在,返回True/False

expire(name, time)

为某个name设置超时时间,单位是秒

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值