作者:糯米不开花ぴ

数据库之 redis

前言:

就学习爬虫而言,对于三种常见的数据库做个基本了解足以,所以笔记都是浅尝辄止,不会涉及太深入的东西。

redis简介

Redis(Remote Dictionary Server ,远程字典服务) 是一个使用ANSI C编写的开源、支持网络、基于内存、可选持久性的键值对存储数据库,是NoSQL数据库(非关系型)。

-------------->>>>>

redis的出现主要是为了替代早期的Memcache缓存系统的。map内存型(数据存放在内存中)的非关系型(nosql)key-value(键值存储)数据库。
支持数据的持久化(基于RDB和AOF,注: 数据持久化时将数据存放到文件中,每次启动redis之后会先将文件中数据加载到内存,经常用来做缓存、数据共享、购物车、消息队列、计数器、限流等。(最基本的就是缓存一些经常用到的数据,提高读写速度)

redis特性

● 速度快
● 持久化
● 多种数据结构
● 支持多种编程语言
● 主从复制
● 高可用、分布式

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,}                       #有序集合
}

 Redis的应用场景

● 缓存系统(“热点”数据:高频读、低频写):缓存用户信息,优惠券过期时间,验证码过期时间、session、token等。
● 计数器:帖子的浏览数,视频播放次数,评论次数、点赞次数等
● 消息队列,秒杀系统
● 社交网络:粉丝、共同好友(可能认识的人),兴趣爱好(推荐商品)
● 排行榜(有序集合)
● 发布订阅:粉丝关注、消息通知

-------------------------------------

在实际中,Redis常和mysql一起使用,通常先把数据存储在Redis,再同步给mysql,查询的时候也是先从Redis中进行查询;例如有时候在网站修改名字不刷新的时候没更新成功,就是因为还在缓存。主要图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的完整安装步骤:

 ❶ 进入GitHub开始下载:

解压zip安装包,解压后的文件目录:

❷ 创建Redis临时服务:

双击启动服务端程序redis.server.exe,界面如下

上图中显示一些 Redis 的相关信息,比如 Redis 的版本号以及默认端口号(6379)。

注意,为了实现后续操作,需要保持服务端开启状态,否则客户端无法正常工作。 

双击启动客户端程序redis.cli.exe,界面如下:说明 Redis 本地客户端与服务端连接成功。

❸ 命令创建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

连接redis

在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连接创建和释放的目的, 从而提高性能。

数据类型操作

(1) 字符串操作

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'

(2) hash操作

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'}

(3) list操作

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'

(4) 集合操作

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'}

(5) 有序集合操作

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']

(6) 键操作

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)