redis操作

 

redis 版本迭代之后,存入的数据类型,再取出来就都是bytes类型了。需要转换一下。

本文转载自wusir博客点击进入

 

redis 删除多个key 示例

hmset key {"k1": "a", "k2": "b"}

del  key  k*
这里直接用k*类似于模糊查询的方法即可实现多个相关的key同时删除,如果不能用模糊查询的话,我们也可以一一列举进行删除

del key k1,k2

 

示例:

 1 import redis
 2 
 3 # conn=redis.Redis(host='192.168.12.79',port=6379)
 4 conn = redis.Redis(host='127.0.0.1', port=6379)
 5 # conn.set('qqx','wahaha')
 6 # val=conn.get('qqx')
 7 # print(val)
 8 # conn.hset('obj','name','wusir')
 9 # print(conn.hget('obj','name'))
10 # conn.hmset('dic',{'a':'a1','b':'b1','c':'c1'})  # hmset是设置多个值,
11 # print(conn.hget('dic','a'))  # 'a1'
12 # print(conn.hget('dic','b'))  # 'b1'
13 # print(conn.hmget('dic','a','c'))  # hmget是获取多个值 [b'a1', b'b1', b'c1']
14 # print(conn.hgetall('dic'))  # 取出所有键值对 {b'a': b'a1', b'b': b'b1', b'c': b'c1'}
15 # print(conn.hlen('dic'))  # 取出长度,3
16 # print(conn.hkeys('dic'))  # [b'a', b'b', b'c']
17 # print(conn.hvals('dic'))  # [b'a1', b'b1', b'c1']
18 # print(conn.hexists('dic','wah'))  # 返回bool值
19 # print(conn.hdel('dic','a','b'))
20 # print(conn.hexists('dic','a'))
21 # conn.hincrby('dic1','a',amount=2)  # 这里是设置了自增2,每一次取值都是从里面取到前一次取出的值+2
22 # print(conn.hget('dic1', 'a'))  # 每一次都执行这一句代码都是在上一次基础上+2
23 # print(conn.hdel('dic1','a'))
24 # conn.hincrbyfloat('dic0','b',amount=1.1)  # 同上,每一次自增1.1可以加上小数
25 # print(conn.hget('dic0','b'))
26 conn.hmset('h1', {'a': 'a1', 'b': 'b1', 'c': 'c1'})  # 这里的hmset是设置多个值
27 
28 # det1,det2=conn.hscan('h1',cursor=0,match=None,count=None)  # 这里是把所有的值都取出来,
29 # print(det1,det2)  # 0 {b'a': b'a1', b'b': b'b1', b'c': b'c1'}det1是索引值
30 
31 data = conn.hscan_iter('h1', match=None, count=12)  # 这里是把我们的数据利用yield封装成hscan创建生成器,
32 # 利用生成器的惰性运算,一个一个把数据取出来,
33 
34 for k, v in data:
35     print(k, v)
36 """
37 惰性运算,利用for循环一次取一个值,避免我们数据量过大从而导致内存崩溃
38 b'a' b'a1'
39 b'b' b'b1'
40 b'c' b'c1'
41 """
简单示例(关于字典的操作)

 

链接池:

import redis
 
pool = redis.ConnectionPool(host='10.211.55.4', port=6379)
 
r = redis.Redis(connection_pool=pool)
r.set('foo', 'Bar')
print r.get('foo')

 

 

我们先把redis安装上,

然后用pip3 install redis   这里是安装我们的python操作这个redis的模块

打开cmd , 输入D: 回车,目录切换到D盘,

我们的redis的安装包在d盘下面,我们要打开redis文件

 

在cmd接着输入命令:

 D:\Program Files\Redis  (redis的文件路径:)

redis-server.exe  "redis.windows.conf"

 

如图显示就可以了

我们如果要连接其他的终端,需要跟ip地址绑定,前提是我们要在redis配置项里面做一些改动

在redis的安装包里面把"redis.windows-service.conf"这个文件打开,一般用notepad++即可打开,全局搜索找到bind 把地址改成0.0.0.0 

这样就可以连接所有的ip了,否则默认是连接自己的ip

 

我们的redis就是一个数据库,

它不是存入到硬盘中的数据库,而是暂存到我们的内存中的,这样存取数据会很快,但是不会永久保存,

我们一般会把常用的数据都放到这个redis里面,提高我们的工作效率,

然后它有自己的api,很多操作指令,我后续会把它们整理出来贴上

 

一个简单的小示例,

import redis
# conn=redis.Redis(host='192.168.12.79',port=6379)  # 这里是连接我们的电脑的ip地址(在cmd里面输入指令ipconfig在ipv4里面可以看到)
conn=redis.Redis(host='127.0.0.1',port=6379)  # 这里是连接我们的本地程序
# conn.set('qqx','wahaha')  # 我们在redis里面存入一个值,第一次存入,就写到内存中,即便后面注释掉它,依然会执行下面的print操作
val=conn.get('qqx')
print(val)

 

 设置过期时间,给指定的key。如下是在redis命令行里面:expire

127.0.0.1:6379> set lmj-name dream  # 先设置key value值
OK
127.0.0.1:6379> expire lmj-name 10  # 再设置过期时间,expire 【key】【seconds】
(integer) 1   # 如果设置成功是返回1,如果不成功或者是该key不存在,则返回0
127.0.0.1:6379> get lmj-name
"dream"

  127.0.0.1:6379> expire lmj 2  # redis没有lmj这个key,设置过期时间不成功,返回0
  (integer) 0

 

 

在项目中redis的应用,以及该如何跟mysql数据库做同步,相关解决办法,收藏转载博客地址:

https://www.cnblogs.com/xiaozengzeng/p/10872290.html 

redis中的发布和订阅

发布者
import
redis con=redis.Redis(host='127.0.0.1',port=6379) con.publish('101.8MH','hello form outside')

 

订阅者
import
redis obj=redis.Redis(host='127.0.0.1',port=6379) con=obj.pubsub() con.subscribe('101.8MH') while True: msg=con.parse_response() print(msg)

先运行我们的订阅者让订阅者夯住等待发布者消息推送,然后再运行发布者.

 

 

这里是我们的redis的高阶用法:

今日内容:
    1. redis
    2. 异步非阻塞
    3. 代码部署
    
内容详细:
    1. redis 
        你了解的redis?
    
        你用redis做过什么?
            - 配合django做缓存,常用且不易修改的数据放进来(博客)
            - 购物车信息
            - Session 
                - 缓存配置文件
                - session配置文件中指定使用缓存
            - rest api中访问频率控制
            - 基于flask、websocket实现的投票系统(redis做消息队列)
            - scrapy中
                - 去重规则
                - 调度器:先进先出、后进先出、优先级队列
                - pipelines 
                - 起始URL
            - 商品热点信息
            - 计数器
            - 排行
        
        为什么redis要做主从复制?
            目的是对redis做高可用,为每一个redis实例创建一个备份称为slave,让主和备之间进行数据同步,save/bsave。
                主:写
                从:读
            优点:
                - 性能提高,从分担读的压力。
                - 高可用,一旦主redis挂了,从可以直接代替。
            
            存在问题:当主挂了之后,需要人为手工将从变成主。
            
        redis的sentinel是什么?
            帮助我们自动在主从之间进行切换
            检测主从中 主是否挂掉,且超过一半的sentinel检测到挂了之后才进行进行切换。
            如果主修复好了,再次启动时候,会变成从。
            
        redis的cluster是什么?
            集群方案:
                - redis cluster 官方提供的集群方案。
                - codis,豌豆荚技术团队。
                - tweproxy,Twiter技术团队。
            redis cluster的原理?
                - 基于分片来完成。
                - redis将所有能放置数据的地方创建了 16384 个哈希槽。
                - 如果设置集群的话,就可以为每个实例分配哈希槽:
                    - 192.168.1.20【0-5000- 192.168.1.21【5001-10000- 192.168.1.22【10001-16384- 以后想要在redis中写值时,
                    set k1 123 
                  将k1通过crc16的算法,将k1转换成一个数字。然后再将该数字和16384求余,如果得到的余数 3000,那么就将该值写入到 192.168.1.20 实例中。
                    
        redis是否可以做持久化?
            RDB:每隔一段时间对redis进行一次持久化。
                 - 缺点:数据不完整
                 - 优点:速度快
            AOF:把所有命令保存起来,如果想到重新生成到redis,那么就要把命令重新执行一次。
                 - 缺点:速度慢,文件比较大
                 - 优点:数据完整
                
        redis的过期策略。
            voltile-lru:    从已设置过期时间的数据集(server.db[i].expires)中挑选最近频率最少数据淘汰
            volatile-ttl:   从已设置过期时间的数据集(server.db[i].expires)中挑选将要过期的数据淘汰
            volatile-random:从已设置过期时间的数据集(server.db[i].expires)中任意选择数据淘汰

            
            allkeys-lru:       从数据集(server.db[i].dict)中挑选最近最少使用的数据淘汰
            allkeys-random:    从数据集(server.db[i].dict)中任意选择数据淘汰
            no-enviction(驱逐):禁止驱逐数据
                        
        redis的分布式锁实现。
            - 写值并设置超时时间
            - 超过一半的redis实例设置成功,就表示加锁完成。
            - 使用:安装redlock-py 
                from redlock import Redlock

                dlm = Redlock(
                    [
                        {"host": "localhost", "port": 6379, "db": 0},
                        {"host": "localhost", "port": 6379, "db": 0},
                        {"host": "localhost", "port": 6379, "db": 0},
                    ]
                )

                # 加锁,acquire
                my_lock = dlm.lock("my_resource_name",10000)
                if  my_lock:
                    # J进行操作
                    # 解锁,release
                    dlm.unlock(my_lock)
                else:
                    print('获取锁失败')
            
        http://www.redis.cn/
        
    2. 异步非阻塞框架:Tornado
        目标:通过一个线程处理N个并发请求。
                - 处理请求IO  :牛逼起来
                - 处理非请求IO:傻逼起来
        
        使用支持tornado异步非阻塞的模块:
            MySQL
            Redis
            SQLALchemy
        
        Tornado异步非阻塞本质:
            视图函数yield一个futrue对象,futrue对象默认:
                self._done = False   ,请求未完成
                self._result = None  ,请求完成后返回值,用于传递给回调函数使用。
            
            tornado就会一直去检测futrue对象的_done是否已经变成True。
            
            如果IO请求执行完毕,自动会调用future的set_result方法:
                        self._result = result
                        self._done = True
        
        参考:http://www.cnblogs.com/wupeiqi/p/6536518.html
            
单台redis的服务器的qbs,读是8万,写是3万,为了提高并发,用户量大的时候可以更快处理用户请求,数据更安全,有更多备份,所以就需要分布式集群,
本质上就是把一部分数据从一台机器上改到多台机器上. redlock redis内部是单进程单线程 redlock安装 使用源码安装,因为在pip库里面还没有它,安装地址:https:
//github.com/SPSCommerce/redlock-py 这里是下载地址,下载后解压,cmd里面cd到该文件下,
然后执行两条命令,python setup.py build python setup.py install 最后显示redlock
-py==1.0.8 就是安装成功 为什么要用这个锁,为了防止两个客户端同时对同一份数据进行操作造成数据丢失. 在redis中我们支持集群,就是可以同时让多个客户端对redis进行操作.这个锁就营运而生了,它是怎么加上的呢,在我们的redis里面加上一个随机字符串,
然后给我们的客户端也加上一个随机字符串,这个时候其他的客户端看到这个字符串就知道是加锁了,就不会对该数据进行操作,会等到锁被释放掉再去执行操作.
在加锁的过程中,我们的这个主从库宕机了,挂掉了,那么这个锁在主从库宕机前就已经加上了,就需要有超时时间,把时间设置上之后,我们的其他客户端就不必遥遥无期的等下去.
还有一种情况就是我们的超时间的设置,如果我们在加锁的过程中,这个过程已经耗时了假设1s,而我们的锁所设置的超时间是0.5s,那么我们把锁设置好了,
就已经过了该锁的超时时间了,此时的锁是没有意义的,不会生效.还有一点是我们的主库如果宕机了,那么哨兵检测到主库挂掉,会把从库提出来作为主库,如果宕机后的主库恢复了,
因为此时已经有主库了,这个恢复后的主库就自动变成从库. 上面是加锁,然后就是释放锁,使用脚本来释放掉锁,当我们在加锁的时候所设定的字符串存在,然后这个字符串的值还必须要跟我们的客户端的值一样,才能删除成功,
通过lua脚本来实现.这样释放掉锁可以避免删除别的客户端获取成功的锁, 还有就是直接向所有的redis实例发送释放锁命令,不关心之前有没有从redis实例中成功获取到锁. 锁的安全和活性失效保障 安全属性:独享(互相排斥),在任意一个时刻,只有一个客户端持有锁. 活性A:无死锁,即便持有锁的客户端崩溃或者网络被分裂,锁仍然可以被获取. 活性B:容错,只要大部分redis节点都活着,客户端留可以获取和释放锁
posted @ 2018-04-20 08:20  dream-子皿  阅读(204)  评论(0)    收藏  举报