034_非关系型数据库Redis_安装配置 & 基础语法 & Python交互

2023-10-27

1. 认识Redis

Redis(Remote Dictionary Server, 远程字典数据服务),是一款内存高速缓存数据库。使用ANSI C语言编写、支持网络、可基于内存亦可持久化的日志型、Key-Value数据库,并提供多种语言的API的非关系型(NoSQL)数据库。
NoSQL(Not Only SQL ),意为“不仅仅是SQL”,泛指非关系型的数据库。NoSQL数据库的产生是为解决大规模数据集多重数据种类带来的挑战,尤其是大数据应用难题,包括超大规模数据的存储。

理解什么是内存高速缓存数据库

  • 对于数据加载速度而言,是硬盘 < 内存 < Cache
  • 缓存有两种类型:1). 页面缓存,经常会用在CMS(content management system)里面;2). 数据缓存,经常会用在页面的具体数据里面。

某商城的页面是适合做数据缓存的,即数据在短时间内不会发生变化,且频繁被访问, 为提高用户的请求速度和降低网站的负载, 将数据放到一个读取速度更快的介质上,称为数据缓存。该介质可以是文件、数据库、内存。内存经常用于数据缓存。

Redis 和 Memcache 的区别(Redis的优点):

对比 Redis Memcache
流行度 流行 下滑
网络IO模型 单核 多核
数据类型 支持多种数据类型 仅支持简单的键值对
数据持久化 支持 不支持
主从模式 支持 不支持
单个Value值最大限制 1GB 1MB
删除机制 惰性删除+定期删除 惰性删除

2. Redis 安装和配置

开发环境:redhat + Redis

step1. 首先上官网下载Redis 压缩包,地址 http://redis.io/download
step2. 压缩包执行解压操作

su -
cd /opt/  # 一般的安装第三方软件的路径
tar xzf redis-5.0.5.tar.gz  # 注意将redis-5.0.5.tar.gz放置在路径 /opt/ 下,并注意压缩包的版本号
cd redis-5.0.5/

step3. 进行编译

方法一:

make

方法二:

sh utils/install_server.sh

step4. 运行,开启Redis服务器

redis-server &

查看一下确实是开启的

>> ps -A | grep redis
 17028 ?        00:00:02 redis-server

step5. 运行,登陆Redis服务端,默认端口为6379,无密码

redis-cli

测试一下:

>> redis-cli
127.0.0.1:6379> ping
PONG
127.0.0.1:6379> set name xiaohua
OK
127.0.0.1:6379> get name
"xiaohua"
127.0.0.1:6379> 

3. Redis 数据类型

  • string 类型:是二进制安全的。可以包含任何数据(eg: jpg 图片或者序列化的对象)。从内部实现来看其实 string 可以看作 byte 数组,最大上限是 1G 字节。
  • hash 类型:是一个 string 类型的 field 和 value 的映射表。它的添加、删除操作都是 O(1)(平均)。
  • list类型:是一个 string 类型的双向链表。最大长度是(232 )。
  • set 类型:是 string 类型的通过 hash table 实现的无序集合。添加、删除和查找的复杂度都是 O(1)。最大长度是(232 )。

4. Redis 内置指令

全面的 Redis 内置指令可参考:Redis | 菜鸟教程https://www.runoob.com/redis/redis-commands.html

sting 数据类型的常用指令示例:

127.0.0.1:6379> set name xiaohua
OK
127.0.0.1:6379> get name
"xiaohua"
127.0.0.1:6379> GETRANGE name 0 3
"xiao"
127.0.0.1:6379> SETRANGE name 4 hong
(integer) 8
127.0.0.1:6379> get name
"xiaohong"
127.0.0.1:6379> SET age 100
OK
127.0.0.1:6379> MGET name age
1) "xiaohong"
2) "100"
127.0.0.1:6379> STRLEN name
(integer) 8
127.0.0.1:6379> INCR age
(integer) 101
127.0.0.1:6379> get age
"101"
127.0.0.1:6379> INCRBY age 10
(integer) 111
127.0.0.1:6379> get age
"111"
127.0.0.1:6379> DECR age
(integer) 110
127.0.0.1:6379> DECRBY age 10
(integer) 100
127.0.0.1:6379> get age
"100"
127.0.0.1:6379> APPEND name -haha
(integer) 13
127.0.0.1:6379> get name
"xiaohong-haha"
127.0.0.1:6379> BITCOUNT name
(integer) 52
127.0.0.1:6379> GETSET name xiaohua
"xiaohong-haha"
127.0.0.1:6379> GETSET name1 xiaohua
(nil)
127.0.0.1:6379> get name1
"xiaohua"
127.0.0.1:6379> 

list 数据类型的常用指令:

127.0.0.1:6379> LPUSH names xiaobai xiaolan xiaohuang
(integer) 3
127.0.0.1:6379> LRANGE names 0 2
1) "xiaohuang"
2) "xiaolan"
3) "xiaobai"
127.0.0.1:6379> RPUSH names xiaoxiao
(integer) 4
127.0.0.1:6379> LRANGE names 0 3
1) "xiaohuang"
2) "xiaolan"
3) "xiaobai"
4) "xiaoxiao"
127.0.0.1:6379> LPOP names
"xiaohuang"
127.0.0.1:6379> RPOP names
"xiaoxiao"
127.0.0.1:6379> GET names
(error) WRONGTYPE Operation against a key holding the wrong kind of value
127.0.0.1:6379> LRANGE names 0 1
1) "xiaolan"
2) "xiaobai"
127.0.0.1:6379> LRANGE names 0 2
1) "xiaolan"
2) "xiaobai"
127.0.0.1:6379> RPOP names
"xiaobai"
127.0.0.1:6379> RPOP names
"xiaolan"
127.0.0.1:6379> BLPOP names 2
(nil)
(2.08s)

等等等…

5. Redis 配置文件——远程登陆

  1. 打开 Redis 的配置文件 一般是 /etc/redis/xxx.conf
vim /etc/redis/redis.conf
  1. 对配置文件进行修改
# 允许所有ip进行绑定
bind 0.0.0.0
# 关闭保护模式 将 yes 修改为 no
protected-mode no
  1. Redis 服务器重新加载配置文件
redis-server /etc/redis/redis.conf

6. Redis 应用场景

Redis 能做什么:

  • 缓存
  • 排行榜 (集合)
  • 计数器/限速器 (统计播放数据、浏览量、在线人数等)
  • 好友关系 (点赞/共同好友 (交并集))
  • 简单消息队列 (订阅发布/阻塞队列)
  • session 服务器 (存储用户session 信息)

Redis 不能做什么:

  • 数据量太大不适合
  • 数据访问频率太低不适合

6.1 Redis 应用——手机手机验证码

"""
限制某段时间内的访问次数,就比如我们登录的功能可以用手机获取验证码登录,但是我们发送验证码使用的第三方,是多少钱多少条的,
肯定不能让他一直点,一直发短信,就算前端js做了校验,若有些人用fiddler拦截绕过前台就麻烦了,
这时候可以用 redis 的 incr 命令和 expire 结合起来做一个解决方案

1. 用户请求了我们的发送短信验证码服务, 用户对应的key(电话号码)
2. 如果缓存中存在了,就是已经请求过验证码了,比如我系统参数设置的至少60秒发送一次短信, 那就代表60之内再次请求了,返回False阻止
3. 否则就是第一次请求短信验证码或者等了60再次请求的验证码, 发送验证码. 放入redis缓存并设置失效时间60秒

"""
import time


def send_msg(phone):
    """模拟给手机发送验证码"""
    import string
    import random
    # 返回一个列表:['4', '1', '5', '9']
    nums_list = random.sample(string.digits, 4)
    nums_code = "".join(nums_list)
    print("%s验证码:%s" %(phone, nums_code))
    return  nums_code

def phone_code(phone):
    """
    电话验证码模拟, 3秒之后可以再次发送验证码
    :param phone:
    :return:
    """
    import redis
    # 实例化 redis 客户端对象,默认:host='localhost', port=6379, password=None...
    client = redis.StrictRedis()
    # 可以从缓存中查询验证码已经发送。
    if client.get(phone):
        print("验证码发送频繁, 请稍后再试")
        return  False
    else:
        code = send_msg(phone)
        # phone:code 3秒之后过期 --> 实现 3 秒之后可以再次发送验证码 
        client.set(phone, code, 3)
        print("发送验证码成功")


if __name__ == '__main__':
    print("第一次发送")
    phone_code('110')
    print("第二次发送")
    phone_code('110')
    time.sleep(4)
    print("第三次发送")
    phone_code('110')

6.2 Redis 应用——基于IP限制HTTP访问频率

"""
IP限制频繁访问:
    如果你运行 HTTP 服务,并且希望限制 HTTP 的访问频率,那么你可以借助一些比较稳定的工具,
    例如: github.com/didip/tollbooth。不过如果你构建的应用比较简单,也可以自己来实现。
IP限制的规则:
    每分钟访问次数不能超过60次。
"""

def ip_limit(IP):
    """
    每分钟访问次数不能超过60次。
    key: value = IP:count
    :param IP:
    :return:
    """
    import redis
    # 实例化 redis 客户端对象,默认:host='localhost', port=6379, password=None...
    client = redis.StrictRedis()
    # 判断是否访问过本服务器
    if client.exists(IP):
        count = client.get(IP).decode('utf-8')
        if int(count) >= 60:
            print("%s访问频繁" %(IP))
        else:
            client.incr(IP)
            print("访问+1")
    else:
        client.set(IP, 1, 60)
        print("%s第一次访问" %(IP))


if __name__ == '__main__':
    for i in range(100):
        ip_limit('127.0.0.1')

6.3 Redis 应用——自行设计列表实现消息队列

"""
Redis: 内存缓存数据库, 消息队列(kafka、RabbitMQ)
# 如何实现高并发场景下抢红包的设计。(思想!相关拓展)
"""
import  queue

class RedisQueue(object):
    """左边为队头, 右边为队尾的消息队列"""
    def __init__(self, name, **conf):
        import redis
        # 实例化 redis 客户端对象
        self.__client = redis.Redis(**conf)
        self.key = name

    def qsize(self):
        return  self.__client.llen(self.key)

    def put(self, item):
        """入队操作"""
        self.__client.rpush(self.key, item)

    def get(self, timeout=5):
        """获取对头, 如果没有到, 等待时间为timeout"""
        item = self.__client.blpop(self.key, timeout=timeout)
        return  item

    def get_nowait(self):
        item = self.__client.blpop(self.key)
        return  item

if __name__ == '__main__':
    q = RedisQueue('scores', host='127.0.0.1', port=6379)
    for i in range(10):
        q.put(i)

    while True:
        result = q.get(timeout=3)
        '''
        result=
        (b'scores', b'0')
		(b'scores', b'1')...
		'''
        print(result)
        if not result:
            break

7. Redis 持久化存储

Redis 是一个内存数据库,与传统的MySQL,Oracle等关系型数据库直接将内容保存到硬盘中相比,内存数据库的读写效率比传统数据库要快的多(内存的读写效率远远大于硬盘的读写效率)。但是数据保存在内存中也随之带来了一个缺点,一旦断电或者宕机,那么内存数据库中的数据将会全部丢失。
于是,持久化就是把内存的数据写到磁盘中去,防止服务宕机了内存数据丢失。
Redis 提供了两种持久化方式:RDB(默认)AOF

  1. RDB,是 Redis 用来进行持久化的一种方式,是把当前内存中的数据集快照写入磁盘,也就是 Snapshot 快照(数据库中所有键值对数据)。恢复时是将快照文件直接读到内存里
  2. AOF,对指令进行备份,当 Redis 重启时会通过重新执行文件中保存的写命令在内存中重建整个数据库中的内容。对于RDB 持久化存,是一定时间内做一次备份,如果 Redis 意外down掉的话,就会丢失最后一次快照后的所有修改(数据有丢失)。

8. Redis 架构

  1. 单机版特点:简单;问题:内存容量有限 、处理能力有限 、无法高可用。
  2. 主从复制:Redis 的复制(replication)功能允许用户根据一个 Redis 服务器来创建任意多个该服务器的复制品,其中被复制的服务器为主服务器(master),而通过复制创建出来的服务器复制品则为从服务器(slave)。 只要主从服务器之间的网络连接正常,主从服务器两者会具有相同的数据,主服务器就会一直将发生在自己身上的数据更新同步给从服务器,从而一直保证主从服务器的数据相同。
    特点:master/slave 角色、master/slave 数据相同、降低 master 读压力再转交从库
    问题:无法保证高可用、没有解决 master 写的压力

9. Python 与 Redis

9.1 实例化对象方式

实例化 Redis 对象的方式正如 Redis 应用中的代码示例,–> 问题:每对数据库的执行一次读写操作时,都需要建立 TCP 连接,严重影响性能

9.2 管道 pipline 优化程序

pipline缓存多条命令,一次性执行,减少服务端与客户端间 TCP 数据包,提高效率
代码示例:

import redis

redis_client = redis.StrictRedis()
# 创建管道pipline 对象即可
pipe = redis_client.pipeline()
pipe.set('name', '小红')
pipe.set('name', '小美')
pipe.set('name', '小白')
pipe.set('name', '小明')
pipe.set('name', '小兰')
# 缓存多条命令,一次性执行
pipe.execute()
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

034_非关系型数据库Redis_安装配置 & 基础语法 & Python交互 的相关文章

  • 531-C++迭代器失效问题及解决方法

    初步在自定义vector类中实现迭代器 迭代器示意图 为什么方式都是一样 因为迭代器遍历完当前元素跳到下一个元素 底层数据结构的具体的遍历方式都封装在这个迭代器的 运算符函数了 所以 作为使用方 我们不需要知道底层的数据结构原理 我们只知道
  • 寄存器堆计算机组成实验,杭电计算机组成原理寄存器堆设计实验4

    杭电计算机组成原理寄存器堆设计实验4 5页 本资源提供全文预览 点击全文预览即可全文预览 如果喜欢文档就下载吧 查找使用更方便哦 9 9 积分 杭州电子科技大学计算机学院实验报告课程名称 计算机组成原理 实验项目 寄存器堆设计实验姓班级 指

随机推荐

  • C语言实现斐波那契数列

    先来说说啥是斐波那契数列 它是一个前两位都为1 从第三位开始 后一位为前两位之和的递增数列 也就是 1 1 2 3 5 8 13 21 34 55 89 我们可以发现 如果你要找第n位的数 其实它就等于第 n 1 位和第 n 2 位之和 那
  • IOS 关于 NSUserDefault

    转载 并不是所有的东西都能往里放的 NSUserDefaults只支持 NSString NSNumber NSDate NSArray NSDictionary NSUserDefaults的方法中用来记录一下永久保留的数据非常方便 不需
  • 大数据手册(Spark)--Spark机器学习(PySpark版)

    文章目录 MLlib ML 常见的特征转换 模型拟合和描述 超参调优 Spark安装配置 Spark基本概念 Spark基础知识 PySpark版 Spark机器学习 PySpark版 Spark流数据处理 PySpark版 MLlib A
  • java创建任意长度空格字符串_输入任意长的一个字符串,统计其字母、数字、空格及其他字符的数量。...

    标签 思路 简单的利用一个多重 if 结构就可以解决 CODE import java util Scanner public class Character public static void main String args Syst
  • 经纬度正则表达式

    经度 180 0 180 0 整数部分为0 180 输入1到8位小数 0 d 1 8 1 9 d d 1 8 1 0 7 d 1 d 1 8 180 0 1 8 纬度 90 0 90 0 整数部分为0 90 输入1到8位小数 0 1 8 d
  • ant上传组件upload,前端读取文件、创建文件

    业务需求是用户上传文件后 还能修改文件内容 最后保存修改后的文件 实现方式 1 前端读取文件内容后显示在代码编辑器中 方便用户修改 2 点保存按钮时 拿到改变的文件内容后 创建新的文件流 提交给后端 这里演示的是JSON文件数据 选择文件
  • 图显系统DRM CRTC完全解析

    目录 CRTC 工作原理和意义 CRTC 模块的初始化和功能 0 引言 DRM 下的 CRTC 代表 RGB 数据管道 从 drm plane 接收像素数据并将其混合到一起 传输给下级显示设备 drm encoder 由 drm displ
  • 原址删除有序数组重复整数

    给定一个有序数组 原址删除重复超过两次的整数 本笔记适合熟悉Python列表list的 coder 翻阅 学习的细节是欢悦的历程 Python 官网 https www python org Free 大咖免费 圣经 教程 python 完
  • Spring中bean创建的生命周期

    1 推断构造方法 2 实例化 3 依赖注入 4 处理Award回调beanFatoryAware 5 初始化前 处理 postConstruct注解 6 初始化 处理iniyializingBean接口 7 初始化前 进行aop
  • Distributed Database System —— Multi-raft协议介绍

    文章目录 Multi Raft协议 Multi Raft需要解决的问题 Multi Raft实现细节 Cockroach Multi Raft Raft Consistency of Range Replicas Range Leaders
  • SQL备份表数据

    1 情况说明 对某个表 需要进行某些删除或修改操作测试 但也需要数据还原 所以需要备份表中数据 2 思路分析 一般操作 将表A所有的数据 备份到新建表B中 若有其他更屌的操作 请告诉我 万分感谢 3 具体SQL实现 库类型说明 SQL SE
  • Java编程--IO流(Ⅱ 字节流)

    Java编程 IO流 字节流 File类虽然可以操作文件 但是并不是操作文件的内容 若要进行文件内容的操作只能通过两种途径完成 字节流和字符流 若要进行输入及输出操作一般都会按照如下的步骤进行 以文件操作为例 1 通过File类定义一个要操
  • 自定义SonarQube Java规则

    自定义SonarQube扫描Java Rule 在介绍如何自定义规则之前 先介绍一下这几个产品 SonarQube 代码质量管理平台 PMD 源代码分析器 FindBugs Java源代码分析器 查找代码Bug Sonar PMD Sona
  • PhotonServer的使用

    https blog csdn net a962035 article details 80713726
  • 一些编译器与解释器的理解

    概述 在19年拜读完Python解释器以及PHP部分解释器并未完全理解 当时主要关心于几个问题 解释器在干嘛 为什么 怎么干的 导致出现区域性片面的理解 直到今年读到内核才逐渐理解 碰巧看到LLVM 大佬思路就是清晰 简单描述个人的理解 如
  • k8s中的有状态,无状态,pv、pvc等

    数据库是一个典型的有状态服务 他的部署和无状态服务是不一样的 PostgresSQL 基于Kubernetes部署PostgresSQL CSDN博客 一 创建SC PV和PVC存储对象 二 部署PostgresSQL Volume Kub
  • dell进入u盘启动模式_uefi不识别u盘怎么办 uefi不识别u盘方法【图文详解】

    现代的电脑配置更新换代都很频繁 从以前的bios主板到现在的uefi主板配置都有很大的进步 而这种新型uefi配置也给新用户装系统带来麻烦 有些用户用u盘启动盘装系统发现uefi不识别u盘 uefi bios识别不了u盘的原因其实就是Lau
  • layui+poi-Java实现导入导出excel文件

    目录 需求说明 一 实现思路 二 前端代码 1 引入layui 2 隐藏部分内容 1 静态页面代码 2 js jquery 代码 点击 导入xx 按钮的js 弹出上面隐藏的内容 3 效果如下 3 下载模板js 4 选择文件 上传js 三 后
  • STM32USB的枚举过程简介

    STM32的USB枚举过程介绍 之前的说明 文中大量引用网上资料 在文后已给出资料的引用说明 文件涉及到的USB各种传输包各个位的含义以及USB标准设备请求的含义都没有做说明 推荐看 圈圈教你玩USB 里面有详细的说明 一 枚举前的工作 系
  • 034_非关系型数据库Redis_安装配置 & 基础语法 & Python交互

    文章目录 1 认识Redis 2 Redis 安装和配置 3 Redis 数据类型 4 Redis 内置指令 5 Redis 配置文件 远程登陆 6 Redis 应用场景 6 1 Redis 应用 手机手机验证码 6 2 Redis 应用