一、redis简介
1、非关系型数据库
2、数据全部是存在内存里面
3、性能非常好,每秒支持30w次读写
4、可以通过备份数据库,把数据存到磁盘上来实现数据的持久化
二、操作redis
1、string类型
1 import redis 2 r = redis.Redis(host='127.0.0.1',password='',db=1,port=6379) # 连接redis 3 r.set('jack','狂') # 数据库里面新增了一个key 4 r.set('jack','疯癫') # key存在用set就可以修改值 5 r.delete('jack') # 删除指定的key 6 r.setex('rose','漂亮',100) # 设置key的失效时间,单位是秒 7 hwt = r.get('jack') # 获取key的值,返回的是二进制数据,如果key不存在则返回None 8 print(hwt.decode()) # 把二进制(bytes)转成字符串 9 print(r.keys()) # 获取所有key 10 print(r.keys('niu*')) # 获取所有'niu'开头的key 11 r.set('双鱼座:niuniu','浪') # 冒号前面就是加的目录名字 12 print(r.get('user:luolei').decode()) # 获取key的值并将二进制(bytes)转化为字符串 13 r.flushdb() # 清空redis 14 # 删除所有的key 15 for k in r.keys(): 16 r.delete(k)
2、hash类型:类似嵌套字典
1 import redis 2 r = redis.Redis(host='127.0.0.1',password='',db=1,port=6379) # 连接redis 3 r.hset('stu_info','刘伟','1000万') # 新增一个key,大key是stu_info,小key是'刘伟' 4 r.hset('stu_info','张流量','交作业0') # 新增一个key,大key是stu_info,小key是'张流量' 5 r.hset('stu_info','董春光','发红包0') # 新增一个key,大key是stu_info,小key是'董春光' 6 print(r.type('stu_info')) # 查看key是什么类型的 7 print(r.hget('stu_info','张流量').decode()) # 指定大key和小key获取对应的value 8 print(r.hgetall('stu_info')) # 获取里面所有的key和value,返回的是一个字典,里面的key和value都是二进制的 9 r.hdel('stu_info','张流量') # 删除指定的key 10 r.delete('stu_info') # 删除整个大key 11 r.expire('jack',100) # 对一个key设置失效时间,string类型和hash类型都可以用 12 # 把r.hgetall返回的字典里面的key和value转成字符串 13 dic = {} 14 for key,value in r.hgetall('stu_info').items(): 15 dic[key.decode()] = value.decode() 16 print(dic)
三、练习
将MySQL表中的数据导入到redis数据库中
1、连接数据库,查到数据库里面所有的数据,游标类型要用pymysql.cursors.DictCursor
2、查到所有的数据:[{"id":1,"passwd":"123","username":"Amy","is_admin":1},......]
3、循环这个list,取到username,把username当做key
4、再把小字典转成json,存成hash的value
1 import pymysql,redis,json 2 r = redis.Redis(host='127.0.0.1',password='',db=1,port=6379) 3 conn = pymysql.connect(host='192.168.1.112',user='test',passwd='111111',port=3306,db='test',charset='utf8') 4 sql = 'select * from my_user;' 5 cur = conn.cursor(cursor=pymysql.cursors.DictCursor) 6 cur.execute(sql) 7 all_data = cur.fetchall() 8 for data in all_data: 9 key = data.get('username') 10 r.hset('stu_info_test',key,json.dumps(data)) 11 cur.close() 12 conn.close()
样例
1 #!/usr/bin/env python 2 # -*- coding: utf-8 -*- 3 import inspect 4 from mgr.common.logger import * 5 from mgr.common.db import * 6 import redis 7 import sys 8 import time 9 10 11 class RedisQueue(object): 12 def __init__(self, mongodb_fuer, queue_name, mgr_ip, node_id, redis_ip='10.186.0.1', port=6379, db=0, pwd=None): 13 self.__db = redis.Redis(host=redis_ip, port=port, db=db, password=pwd) 14 self.__queue_name = queue_name 15 self.__mgr_ip = mgr_ip 16 self.__node_id = node_id 17 self._resource_collections = mongodb_fuer['resource'] 18 19 def rpush(self, *args): 20 self.__db.rpush(self.__queue_name, *args) 21 # LOG_DEBUG('从队列右侧插入数据: {}'.format(args)) 22 23 def lpush(self, *args): 24 self.__db.lpush(self.__queue_name, *args) 25 # LOG_DEBUG('从队列左侧插入数据: {}'.format(args)) 26 27 def rpop(self): 28 data = self.__db.rpop(name=self.__queue_name) 29 # LOG_DEBUG('从队列右侧获取数据: {}'.format(data)) 30 31 def lpop(self): 32 data = self.__db.lpop(name=self.__queue_name) 33 # LOG_DEBUG('从队列左侧获取数据: {}'.format(data)) 34 return data 35 36 @property 37 def qsize(self): 38 q_len = self.__db.llen(name=self.__queue_name) 39 # LOG_DEBUG('当前队列长度为: {}'.format(q_len)) 40 return q_len 41 42 def qrange(self, start_index=0, end_index=-1): 43 queue_content = self.__db.lrange(name=self.__queue_name, start=start_index, end=end_index) 44 # LOG_DEBUG('指定的队列为: {}'.format(queue_content)) 45 return queue_content 46 47 def qclear(self): 48 # 清空队列 49 # LOG_DEBUG('清空队列') 50 for i in range(self.__db.llen(name=self.__queue_name)): 51 self.__db.lpop(name=self.__queue_name) 52 53 def loop_read_resource(self, timeout=3600, **kwargs): 54 # 轮询等待资源解锁 55 kwargs = {k: str(v) for k, v in kwargs.items()} 56 kwargs.update({'mgr_ip': self.__mgr_ip}) 57 count = 0 58 if int(timeout): 59 while True: 60 if timeout >= 0: 61 data = self._resource_collections.find_one(filter=kwargs) 62 if data: 63 # LOG_DEBUG('轮询筛选资源数据的条件为: {}'.format(kwargs)) 64 # LOG_DEBUG('轮询访问获得资源数据为: {}'.format(data)) 65 return data 66 else: 67 timeout -= 5 68 count += 1 69 if count != 0 and count % 60 == 0: 70 # 5分钟打印一次日志 71 LOG_DEBUG('node_id: {} is waiting for db: {}'.format(self.__node_id, kwargs)) 72 LOG_DEBUG('waited time is : {}min'.format(count * 5 / 60)) 73 time.sleep(5) 74 else: 75 # LOG_DEBUG('轮询时间超时,获得资源数据为空') 76 return {} 77 78 def lock_resource(self, update_param, filter_param={'lock': '0'}, timeout=5400): 79 # 轮询等待修改资源配置 80 filter_param = {k: str(v) for k, v in filter_param.items()} 81 filter_param.update({'mgr_ip': self.__mgr_ip}) 82 if 'lock' not in filter_param.keys(): 83 filter_param.update({'lock': '0'}) 84 update_param = {k: str(v) for k, v in update_param.items()} 85 # 用于打印日志 86 loop_count = 0 87 previous_frame = inspect.currentframe().f_back 88 caller_filename, caller_line_number, caller_function_name, caller_lines, caller_index = inspect.getframeinfo(previous_frame) 89 while True: 90 if loop_count % 60 == 0: 91 # 每等待5分钟资源配置,输出日志辅助调试 92 LOG_DEBUG('*' * 40) 93 LOG_DEBUG('node_id: {} is waited {} min, filter_param: {}, update_param: {}'.format(self.__node_id, (loop_count * 5)/60, filter_param, update_param)) 94 LOG_DEBUG('current redis queue is : {}'.format(self.qrange())) 95 LOG_DEBUG('lock_resource caller_filename: {}'.format(caller_filename)) 96 LOG_DEBUG('lock_resource caller_function_name: {}'.format(caller_function_name)) 97 LOG_DEBUG('*' * 40) 98 # if loop_count >= 6 * 6