前言:
就学习爬虫而言,对于三种常见的数据库做个基本了解足以,所以笔记都是浅尝辄止,不会涉及太深入的东西。
Redis(Remote Dictionary Server ,远程字典服务) 是一个使用ANSI C编写的开源、支持网络、基于内存、可选持久性的键值对存储数据库,是NoSQL数据库(非关系型)。
-------------->>>>>
redis的出现主要是为了替代早期的Memcache缓存系统的。map内存型(数据存放在内存中)的非关系型(nosql)key-value(键值存储)数据库。
支持数据的持久化(基于RDB和AOF,注: 数据持久化时将数据存放到文件中,每次启动redis之后会先将文件中数据加载到内存,经常用来做缓存、数据共享、购物车、消息队列、计数器、限流等。(最基本的就是缓存一些经常用到的数据,提高读写速度)。
● 速度快
● 持久化
● 多种数据结构
● 支持多种编程语言
● 主从复制
● 高可用、分布式
Redis提供的数据类型主要分为5种自有类型和一种自定义类型。
这5种自有类型包括:String类型、哈希类型、列表类型、集合类型和顺序集合类型。
示例如下:
#很像python的一个大字典:
redis={
"name":"hailey", #String类型
"age":"23", #String--数字类型
"scors":[78,79,98,], #list类型
"info":{"gender":"male","tel":"110"}, #哈希类型,键值结构嵌套键值
"set":{1,2,3}, #集合类型
"zset":{1,2,3,} #有序集合
}
● 缓存系统(“热点”数据:高频读、低频写):缓存用户信息,优惠券过期时间,验证码过期时间、session、token等。
● 计数器:帖子的浏览数,视频播放次数,评论次数、点赞次数等
● 消息队列,秒杀系统
● 社交网络:粉丝、共同好友(可能认识的人),兴趣爱好(推荐商品)
● 排行榜(有序集合)
● 发布订阅:粉丝关注、消息通知-------------------------------------
在实际中,Redis常和mysql一起使用,通常先把数据存储在Redis,再同步给mysql,查询的时候也是先从Redis中进行查询;例如有时候在网站修改名字不刷新的时候没更新成功,就是因为还在缓存。主要图Redis存储特别快。
官方原版: https://redis.io/
虽然 Redis 官方网站没有提供 Windows 版的安装包,但可以通过 GitHub 来下载 Windows 版 Redis 安装包
下载地址:点击前往
=====================================================================
安装时一路next
★ 到“ Destination Folder”界面选择安装目录、勾选add path全局变量
★ “ort Number and Firewall Exception”端口号默认:6379
★ “Memory Limit”勾选“Set the Max Memory lmit”可修改Max Memory MB,即redis占用内存的限制。
下面详细记录windows的完整安装步骤:
解压zip安装包,解压后的文件目录:
双击启动服务端程序redis.server.exe,界面如下
上图中显示一些 Redis 的相关信息,比如 Redis 的版本号以及默认端口号(6379)。
注意,为了实现后续操作,需要保持服务端开启状态,否则客户端无法正常工作。
双击启动客户端程序redis.cli.exe,界面如下:说明 Redis 本地客户端与服务端连接成功。
上述方式虽然简单快捷,但是显然不是程序员的操作,下面介绍,通过命令启动 Redis 服务端,并将 Redis 服务添加到 Windows 资源管理器,实现开机后自动启动。
注册Redis服务
通过 CMD 命令行工具进入 Redis 安装目录,将 Redis 服务注册到 Windows 服务中,执行以下命令:
redis-server.exe --service-install redis.windows.conf --loglevel verbose
执行后输出8060这两行,说明注册成功:
启动Redis服务
执行以下命令启动 Redis 服务,命令如下:
redis-server --service-start
执行启动后,如下所示:
注意:
此时 Redis 已经被添加到 Windows 服务中(cmd中输入services.msc),因此不会再显示 Redis 服务端的相应的信息:
启动Redis客户端
在 CMD 命令行输出 redis-cli 命令启动客户端
redis-cli
如下:
检查是否连接成功
测试客户端和服务端是否成功连接。输出PING
命令,若返回PONG
则证明成功连接:
此电脑 -> 右击“属性” -> 高级系统设置 -> 环境变量 ->系统变量(s) -> 双击path -> 新建,填写路径
安装服务:redis-server --service-install
卸载服务:redis-server --service-uninstall
开启服务:redis-server --service-start
停止服务:redis-server --service-stop
服务端启动时重命名:redis-server --service-start --service-name Redis1
在python中有一个专门的redis第三库
还是需要先进行安装:pip install redis
引用:import redis
链接方式1:
import redis(在python中improt之前,本地还是需要先进行安装redis)
r = redis.Redis(host='本地ip', port=6379) #本机链接也可省略host和port
r.set('foo', 'Bar') #写入数据
print(r.get('foo')) #获取数据
链接方式2:
import redis
pool = redis.ConnectionPool(host='服务器ip', port=6379) #远程链接必须写
r = redis.Redis(connection_pool=pool)
r.set('bar', 'Foo') #写入数据
print(r.get('bar')) #获取数据
通常情况下, 当我们需要做redis操作时, 会创建一个连接, 并基于这个连接进行redis操作, 操作完成后, 释放连接,一般情况下, 这是没问题的, 但当并发量比较高的时候, 频繁的连接创建和释放对性能会有较高的影响。
于是, 连接池就发挥作用了。连接池的原理是, 通过预先创建多个连接, 当进行redis操作时, 直接获取已经创建的连接进行操作, 而且操作完成后, 不会释放, 用于后续的其他redis操作。
这样就达到了避免频繁的redis连接创建和释放的目的, 从而提高性能。
import redis
pool = redis.ConnectionPool(host='ip', port=6379, db=0, decode_responses=True)
r = redis.Redis(connection_pool=pool)
#字符串操作:不允许对已经存在的键设置值
ret = r.setnx("name", "eric")
print(ret) # False
#设置键有效期
r.setex("good_1001", 10, "2")
#字符串操作:自增自减
r.set("age", 20)
r.incrby("age", 2)
print(r.get("age")) # b'22'
import redis
pool = redis.ConnectionPool(host='ip', port=6379, db=0, decode_responses=True)
r = redis.Redis(connection_pool=pool)
r.hset("info", "name", "rain")
print(r.hget("info", "name")) # b'rain'
r.hmset("info", {"gedner": "male", "age": 22})
print(r.hgetall("info")) # {b'name': b'rain', b'gender': b'male', b'age': b'22'}
import redis
pool = redis.ConnectionPool(host='ip', port=6379, db=0, decode_responses=True)
r = redis.Redis(connection_pool=pool)
r.rpush("scores", "100", "90", "80")
r.rpush("scores", "70")
r.lpush("scores", "120")
print(r.lrange("scores", 0, -1)) # ['120', '100', '90', '80', '70']
r.linsert("scores", "AFTER", "100", 95)
print(r.lrange("scores", 0, -1)) # ['120', '100', '95', '90', '80', '70']
print(r.lpop("scores")) # 120
print(r.rpop("scores")) # 70
print(r.lindex("scores", 1)) # '95'
import redis
pool = redis.ConnectionPool(host='ip', port=6379, db=0, decode_responses=True)
r = redis.Redis(connection_pool=pool)
# key对应的集合中添加元素
r.sadd("name_set", "zhangsan", "lisi", "wangwu")
# 获取key对应的集合的所有成员
print(r.smembers("name_set")) # {'lisi', 'zhangsan', 'wangwu'}
# 从key对应的集合中随机获取 numbers 个元素
print(r.srandmember("name_set", 2))
r.srem("name_set", "lisi")
print(r.smembers("name_set")) # {'wangwu', 'zhangsan'}
import redis
pool = redis.ConnectionPool(host='ip', port=6379, db=0, decode_responses=True)
r = redis.Redis(connection_pool=pool)
# 在key对应的有序集合中添加元素
r.zadd("jifenbang", {"yuan": 78, "rain": 20, "alvin": 89, "eric": 45})
# 按照索引范围获取key对应的有序集合的元素
# zrange( name, start, end, desc=False, withscores=False, score_cast_func=float)
print(r.zrange("jifenbang", 0, -1)) # ['rain', 'eric', 'yuan', 'alvin']
print(r.zrange("jifenbang", 0, -1, withscores=True)) # ['rain', 'eric', 'yuan', 'alvin']
print(r.zrevrange("jifenbang", 0, -1, withscores=True)) # ['rain', 'eric', 'yuan', 'alvin']
print(r.zrangebyscore("jifenbang", 0, 100))
print(r.zrangebyscore("jifenbang", 0, 100, start=0, num=1))
# 删除key对应的有序集合中值是values的成员
print(r.zrem("jifenbang", "yuan")) # 删除成功返回1
print(r.zrange("jifenbang", 0, -1)) # ['rain', 'eric', 'alvin']
import redis
pool = redis.ConnectionPool(host='ip', port=6379, db=0, decode_responses=True)
r = redis.Redis(connection_pool=pool)
r.delete("scores")
print(r.exists("scores"))
print(r.keys("*"))
r.expire("name",10)