zoukankan      html  css  js  c++  java
  • 缓存数据库之redis

    NoSQL(NoSQL = Not Only SQL ),意即“不仅仅是SQL”,泛指非关系型的数据库,NoSQL数据库的产生就是为了解决大规模数据集合多重数据种类带来的挑战,尤其是大数据应用难题

    NoSQL数据库的四大分类

    分类Examples举例典型应用场景数据模型优点缺点
    键值(key-value) Tokyo Cabinet/Tyrant, Redis, Voldemort, Oracle BDB 内容缓存,主要用于处理大量数据的高访问负载,也用于一些日志系统等等。 Key 指向 Value 的键值对,通常用hash table来实现 查找速度快 数据无结构化,通常只被当作字符串或者二进制数据
    列存储数据库 Cassandra, HBase, Riak 分布式的文件系统 以列簇式存储,将同一列数据存在一起 查找速度快,可扩展性强,更容易进行分布式扩展 功能相对局限
    文档型数据库 CouchDB, MongoDb Web应用(与Key-Value类似,Value是结构化的,不同的是数据库能够了解Value的内容) Key-Value对应的键值对,Value为结构化数据 数据结构要求不严格,表结构可变,不需要像关系型数据库一样需要预先定义表结构 查询性能不高,而且缺乏统一的查询语法。
    图形(Graph)数据库 Neo4J, InfoGrid, Infinite Graph 社交网络,推荐系统等。专注于构建关系图谱 图结构 利用图结构相关算法。比如最短路径寻址,N度关系查找等 很多时候需要对整个图做计算才能得出需要的信息,而且这种结构不太好做分布式的集群方案。

    redis是业界主流的key-value nosql 数据库之一。 键的类型是字符串且不能重复,值的类型可以分为五种字符串、哈希、列表、集合、有序集合。

    安装Redis环境

    要在 Ubuntu 上安装 Redis,打开终端,然后输入以下命令:
    $sudo apt-get update
    $sudo apt-get install redis-server
    
    这将在您的计算机上安装Redis

    启动 Redis

    $redis-server
    

    查看 redis 是否还在运行

    $redis-cli
    
    这将打开一个 Redis 提示符,如下图所示:
    redis 127.0.0.1:6379>
    
    在上面的提示信息中:127.0.0.1 是本机的IP地址,6379是 Redis 服务器运行的端口。现在输入 PING 命令,如下图所示:
    redis 127.0.0.1:6379> ping
    PONG
    
    这说明现在你已经成功地在计算机上安装了 Redis。
     
    连接方式
    import redis
      
    r = redis.Redis(host='10.211.55.4', port=6379)
    r.set('foo', 'Bar')
    print r.get('foo')
    View Code

    连接池,redis-py使用connection pool来管理对一个redis server的所有连接,避免每次建立、释放连接的开销。默认,每个Redis实例都会维护一个自己的连接池。可以直接建立一个连接池,然后作为参数Redis,这样就可以实现多个Redis实例共享一个连接池。

    import redis
    
    pool = redis.ConnectionPool(host='192.168.0.110', port=6379)
    r = redis.Redis(connection_pool=pool)
    r.set('name', 'xmen')   #添加
    print (r.get('name'))   #获取
    View Code

    管道,redis-py默认在执行每次请求都会创建(连接池申请连接)和断开(归还连接池)一次连接操作,如果想要在一次请求中指定多个命令,则可以使用pipline实现一次请求指定多个命令,并且默认情况下一次pipline 是原子性操作

    import redis
    pool = redis.ConnectionPool(host='192.168.0.110', port=6379)
    r = redis.Redis(connection_pool=pool)
    
    pipe = r.pipeline(transaction=True)
    
    r.set('name', 'zhangsan')
    r.set('name', 'lisi')
    
    pipe.execute()
    View Code

    发布和订阅

    首先定义一个RedisHelper类,连接Redis,定义频道为monitor,定义发布(publish)及订阅(subscribe)方法

    import redis
    
    class RedisHelper(object):
        def __init__(self):
            self.__conn = redis.Redis(host='192.168.0.110',port=6379)#连接Redis
            self.channel = 'monitor' #定义名称
    
        def publish(self,msg):#定义发布方法
            self.__conn.publish(self.channel,msg)
            return True
    
        def subscribe(self):#定义订阅方法
            pub = self.__conn.pubsub()
            pub.subscribe(self.channel)
            pub.parse_response()
            return pub
    View Code

    发布者

    from RedisHelper import RedisHelper
    
    obj = RedisHelper()
    obj.publish('hello')#发布
    View Code

    订阅者

    from RedisHelper import RedisHelper
    
    obj = RedisHelper()
    redis_sub = obj.subscribe()#调用订阅方法
    
    while True:
        msg= redis_sub.parse_response()
        print (msg)
    View Code

     

    基本操作

    String操作 表现形式k1—>v1

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

    setnx(name, value)

    setex(name, value, time)#设置过期时间

    psetex(name, time_ms, value)

    mset(*args, **kwargs)#设置多个键值

    get(name)#获取值

    mget(keys, *args)#批量获取

    getset(name, value)#设置新值并获取原来的值

    getrange(key, start, end)# 获取子序列(根据字节获取,非字符)

    setrange(name, offset, value)# 修改字符串内容,从指定字符串索引开始向后替换(新值太长时,则向后添加)

    setbit(name, offset, value)# 对name对应值的二进制表示的位进行操作

    getbit(name, offset)# 获取name对应的值的二进制表示中的某位的值 (0或1)

    bitcount(key, start=None, end=None)# 获取name对应的值的二进制表示中 1 的个数

    strlen(name)# 返回name对应值的字节长度(一个汉字3个字节)

    incr(self, name, amount=1)# 自增 name对应的值,当name不存在时,则创建name=amount,否则,则自增。

    incrbyfloat(self, name, amount=1.0)# 自增 name对应的值,当name不存在时,则创建name=amount,否则,则自增。

    decr(self, name, amount=1)# 自减 name对应的值,当name不存在时,则创建name=amount,否则,则自减。

    append(key, value)# 在redis name对应的值后面追加内容

     Hash操作,表现形式上有些像pyhton中的dict,可以存储一组关联性较强的数据 。k1——>{Kx—>Vx}

    hset(name, key, value)# name对应的hash中设置一个键值对(不存在,则创建;否则,修改)

    hmset(name, mapping)# 在name对应的hash中批量设置键值对

    hget(name,key)# 在name对应的hash中获取根据key获取value

    hmget(name, keys, *args)# 在name对应的hash中获取多个key的值

    hgetall(name)#获取name对应hash的所有键值

    hlen(name)# 获取name对应的hash中键值对的个数

    hkeys(name)# 获取name对应的hash中所有的key的值

    hvals(name)# 获取name对应的hash中所有的value的值

    hexists(name, key)# 检查name对应的hash是否存在当前传入的key

    hdel(name,*keys)# 将name对应的hash中指定key的键值对删除

    hincrby(name, key, amount=1)# 自增name对应的hash中的指定key的值,不存在则创建key=amount

    hincrbyfloat(name, key, amount=1.0)# 自增name对应的hash中的指定key的值,不存在则创建key=amount

    hscan_iter(name, match=None, count=None)# 利用yield封装hscan创建生成器,实现分批去redis中获取数据

    List操作,redis中的List在在内存中按照一个name对应一个List来存储

    lpush(name,values)# 在name对应的list中添加元素,每个新的元素都添加到列表的最左边

    lpushx(name,value)# 在name对应的list中添加元素,只有name已经存在时,值添加到列表的最左边

    llen(name)# name对应的list元素的个数

    linsert(name, where, refvalue, value))# 在name对应的列表的某一个值前或后插入一个新值

    lset(name, index, value)# 对name对应的list中的某一个索引位置重新赋值

    lrem(name, value, num)# 在name对应的list中删除指定的值

    lpop(name)# 在name对应的列表的左侧获取第一个元素并在列表中移除,返回值则是第一个元素

    lindex(name, index)#在name对应的列表中根据索引获取列表元素

    lrange(name, start, end)# 在name对应的列表分片获取数据

    ltrim(name, start, end)# 在name对应的列表中移除没有在start-end索引之间的值

    rpoplpush(src, dst)# 从一个列表取出最右边的元素,同时将其添加至另一个列表的最左边

    blpop(keys, timeout)# 将多个列表排列,按照从左到右去pop对应列表的元素

    brpoplpush(src, dst, timeout=0)# 从一个列表的右侧移除一个元素并将其添加到另一个列表的左侧

    Set操作,Set集合就是不允许重复的列表

    sadd(name,values)# name对应的集合中添加元素

    scard(name)获取name对应的集合中元素个数

    sdiff(keys, *args)在第一个name对应的集合中且不在其他name对应的集合的元素集合

    sdiffstore(dest, keys, *args)# 获取第一个name对应的集合中且不在其他name对应的集合,再将其新加入到dest对应的集合中

    sinter(keys, *args)# 该集合是所有给定集合的交集

    sinterstore(dest, keys, *args)# 获取多一个name对应集合的并集,再讲其加入到dest对应的集合中

    sismember(name, value)# 检查value是否是name对应的集合的成员

    smembers(name)# 获取name对应的集合的所有成员

    smove(src, dst, value)# 将某个成员从一个集合中移动到另外一个集合

    spop(name)# 从集合的右侧(尾部)移除一个成员,并将其返回

    srandmember(name, numbers)# 从name对应的集合中随机获取 numbers 个元素

    srem(name, values)# 在name对应的集合中删除某些值

    sunion(keys, *args)# 获取多一个name对应的集合的并集

    sunionstore(dest,keys, *args)# 获取多一个name对应的集合的并集,并将结果保存到dest对应的集合中

    sscan(name, cursor=0, match=None, count=None)
    sscan_iter(name, match=None, count=None)# 同字符串的操作,用于增量迭代分批获取元素,避免内存消耗太大

    有序集合,在集合的基础上,为每元素排序;元素的排序需要根据另外一个值来进行比较,所以,对于有序集合,每一个元素有两个值,即:值和分数,分数专门用来做排序。

    zadd(name, *args, **kwargs)# 在name对应的有序集合中添加元素

    zcard(name)# 获取name对应的有序集合元素的数量

    zcount(name, min, max)# 获取name对应的有序集合中分数 在 [min,max] 之间的个数

    zincrby(name, value, amount)# 自增name对应的有序集合的 name 对应的分数

    zrange( name, start, end, desc=False, withscores=False, score_cast_func=float)# 按照索引范围获取name对应的有序集合的元素

    zrank(name, value)# 获取某个值在 name对应的有序集合中的排行(从 0 开始)

    zrem(name, values)# 删除name对应的有序集合中值是values的成员

    zremrangebyrank(name, min, max)# 根据排行范围删除

    zremrangebyscore(name, min, max)# 根据分数范围删除

    zscore(name, value)# 获取name对应有序集合中 value 对应的分数

    zinterstore(dest, keys, aggregate=None)# 获取两个有序集合的交集,如果遇到相同值不同分数,则按照aggregate进行操作,aggregate的值为:  SUM  MIN  MAX

    zunionstore(dest, keys, aggregate=None)# 获取两个有序集合的并集,如果遇到相同值不同分数,则按照aggregate进行操作

    其他常用操作

    delete(*names)# 根据删除redis中的任意数据类型

    exists(name)# 检测redis的name是否存在

    keys(pattern='*')# 根据模型获取redis的name

    expire(name ,time)# 为某个redis的某个name设置超时时间

    rename(src, dst)# 对redis的name重命名为

    move(name, db))# 将redis的某个值移动到指定的db下

    randomkey()# 随机获取一个redis的name(不删除)

    type(name)# 获取name对应值的类型

    scan(cursor=0, match=None, count=None)# 同字符串操作,用于增量迭代获取key
    scan_iter(match=None, count=None)

  • 相关阅读:
    Thread--使用condition实现顺序执行
    Thread--condition
    Thread--lock,lockInterruptibly,tryLock,tryLock(long timeout, TimeUnit unit)
    Thread--线程间通信--管道
    Thread--生产者消费者假死分析
    Thread--生产者消费者
    Java--定时
    Thread--两线程交替打印
    重装系统都杀不掉的十大病毒
    常用工具
  • 原文地址:https://www.cnblogs.com/master-song/p/9439775.html
Copyright © 2011-2022 走看看