学习redis之前的泛泛而谈(特性介绍,应用场景,Ubuntu安装与通用命令介绍)

news2024/11/18 7:37:23

文章目录

    • 前言
    • 关于分布式系统
    • Redis特性
    • Redis应用场景
    • Redis5安装
    • redis命令
      • 最核心的两个命令:get和set
      • keys
      • exits
      • del
      • expire
      • ttl
      • redis中key的过期策略
      • type
    • redis数据类型的内部实现方式
    • redis的单线程

前言

redis最重要的概念:在内存中存储数据
为什么要设计一个在内存中存储数据的数据库,定义的变量天然就存储在内存中,为什么不直接定义变量?
另一个重要的概念:分布式,在单机系统中,使用redis显得多此一举,只有在分布式系统中使用redis才能发挥它真正的性能

可以这样理解:redis基于网络,将内存中的变量,分享给其他进程甚至其他主机的进程使用

为什么不直接使用MySQL?
MySQL最大的问题在于,因为它使用硬盘进行存储。而某些应用对于速度相应的要求极高,此时只能使用redis

而redis最大的劣势在于内存有限,能存储的数据量小。将redis和MySQL结合,将20%的热点数据用redis存储,而80%的非热点数据用MySQL存储,就能使结合后的数据库的又大又快。此时redis相当于MySQL的cache,这也是冷热分离架构的关键,但是这样做的代价就是大大提升了系统的复杂程度

(redis最开始的目的是研发一个消息中间件streaming engine,即分布式系统下的生产消费模型。但随着慢慢地发展,大家发现将redis作为数据库来使用是更好的选择。即使redis也支持消息中间件的功能,但市面中存在更多专业的中间件供我们使用,因此对于redis消息队列相关的知识不作为重点学习)

以上文字中,“分布式”被频繁提及,事实也是如此:要谈Redis就离不开分布式

关于分布式系统

要谈分布式就离不开互联网产品架构的演进过程
早期的单机架构:应用服务和数据服务部署在一台主机上,而一台主机的资源有限,包括但不限于:CPU、内存、磁盘、网络…随着用户的请求增多,主机的资源不够使用时,如何处理?
两个方面:1. 开源:简单粗暴,增加更多的硬件资源 2. 节流:从软件上优化,找到性能凭借并解决,节省软件的资源消耗(难)

对于开源,虽然增加硬件资源更加容易,但是一台主机硬件资源存在上限,这个上限由主板的扩展能力决定
既然垂直扩展不行,那就水平扩展,水平扩展就是引入更多的主机,而主机一多,就需要在软件上进行相应的调整和适配
围绕着软件的调整和适配,互联网应用的架构就开始了演进,分布式系统架构就属于演进中的关键一环(不太准确的说:就是使用多台主机/节点存储数据)。至于具体的演进,这里不再赘述,有兴趣可以看我写的上一篇文章

Redis特性

根据官网给出的资料:

  • 使用内存存储数据结构(In-memory data structures):Redis作为非关系型数据库,用数据结构存储数据。数据结构一般都是键值对,以string作为key,string, hash, list, set, zset…作为value。相比于关系型数据库以“表”的方式存储数据,非关系型数据库的存储方式显然更简单
  • 可编程(Programmability):对于Redis,可以使用简单的命令进行交互,也可以使用脚本语言Lua执行一些带有简单逻辑的操作
  • 可扩展(Extensibility):Redis提供了一组API,可以使用C,C++,Rust语言调用这些API。因此我们能自主地扩展Redis的功能(本质上是使用API编写动态链接库)
  • 持久化(Persistence):Redis主要使用内存存储数据,并且以硬盘作为辅助。Redis会将内存中的数据持久化到硬盘中,若系统发生问题导致了重启,那么Redis会从硬盘读取备份数据
  • 集群化(Clustering):类似于分库分表,可以部署多个Redis节点用来存储数据,每个节点存储整体数据的一部分
  • 高可用(High availability):即数据的备份。Redis支持主从结构,主节点崩溃,从节点马上顶上代替主节点,这个过程用时极短,用户甚至感知不到

最重要的一个特性是:快,为什么?

  1. Redis存储在内存中
  2. Redis作为非关系型数据库,核心功能的逻辑简单,执行效率高
  3. 从网络上看,Redis使用IO多路复用(epoll)
  4. Redis为单线程模型,减少了不必要的线程竞争开销(为什么Redis中,单线程比多线程快?多线程更快的场景为:CPU密集型任务,此时多线程能充分地利用CPU多核资源。而Redis的任务只是简单的操作数据结构,不是CPU密集型任务,使用多线程反而会变慢)

Redis应用场景

  • 实时数据存储(Real-time data store):将Redis作为数据库使用。对于大多数应用,它们的数据存储需要优先考虑“大”,但是对于一部分应用,它们的数据存储需要优先考虑“快”。如搜索引擎对于性能的要求非常高,需要将所有的数据存储在内存中,此时可用考虑Redis
  • 缓存与会话存储(Caching & session storage):在冷热分离架构中,Reids作为MySQL的辅助,存储热点数据以提高访问热点数据的速度。此时Redis只是一个辅助,若Redis崩溃了,数据还能从MySQL中恢复。会话存储:访问web应用时,本地浏览器用cookie保存了用户的身份信息,而远端服务器用session存储用户信息,只有两者的信息匹配,才能成功验证用户信息。但在应用服务集群中,每次访问的应用服务器可能都不相同,此时将出现一台服务器保存了session,而其他服务器没有保存session。为了减少用户的验证次数,采用Redis保存用户session,服务器从Redis中更新用户session
  • 消息队列(Streaming & messaging):基于Redis的消息队列可以实现一个基于网络的生产消费模型。若当前应用中已经使用了Redis,又不想引入其他的中间件时,可以考虑Redis的消息队列

Redis不能做的事:存储大规模数据

Redis5安装

安装

apt install -y redis

验证

redis-server --version
netstat -nltp | grep redis

image.png

发现redis只开放了本地环回的端口,意味着不能从外网连接redis服务,这里修改配置文件,使外网IP也能访问redis服务

cd /etc/redis

image.png

其中的redis.conf就是redis的配置文件(通过配置文件开启/关闭/设定软件的某些功能)
编辑该文件

vim redis.conf

找到bind这句话
image.png
将127.0.0.1修改成0.0.0.0即可
image.png
再找到protected-mode,将yes修改为no
image.png

最后重启服务器使配置生效

service redis-server restart  # 重启redis服务
service redis-server status   # 查看redis运行状态

image.png
active(running)表示正常运行,此时修改配置文件成功

使用redis客户端连接服务器,输入以下语句即可

redis-cli

image.png
输入ping,返回PONG说明连接成功
ctrl+d退出redis客户端

redis命令

同mysql一样,redis也是客户端-服务器程序
redis的快体现在:与关系型数据库相比(如MySQL),redis快很多。但是与直接在内存中定义数据结构存储数据相比,redis就慢得多了。因为redis是客户端服务器程序,相比于直接操作内存,redis还需要先进行网络传输以获取操作命令

通过官网Redis中的搜索框,输入命令就能查看命令的相关文档
image.png

最核心的两个命令:get和set

哈希表怎么用,redis就怎么用

set:将键值对存入数据库

set key value

image.png

对于key和value,没有必要加引号

get:根据key取value
如果kv不存在,将返回nil
image.png

keys

key固定为字符串,但value有多种类型,常见的有五种:字符串、哈希表、列表、集合、有序集合,操作不用的数据结构,就有不同的命令。全局命令则能操作任意数据结构,keys就是一个全局命令

keys:通过一些特殊符号(通配符)描述key,匹配描述的key将被返回

keys pattern

pattern用来描述key需要符合的条件

  • ?匹配一个字符
  • *匹配一个/多个字符
  • [aef]只能匹配a或者e或者f(给出固定的选项)
  • [^e]除了e都能匹配(排除e)
  • [a-e]a到e之间的字符都可选,包含a和e

image.png

image.png

image.png

keys的时间复杂度为 O ( n ) O(n) O(n),生产环境中进行使用keys,特别是keys *
因为redis是单线程程序,keys将导致redis被阻塞,使得MySQL的负载升高,可能导致redis和MySQL都一起挂掉,甚至系统崩溃

exits

返回key存在的个数(针对n个key,只会返回0~n之间的数)

exits key [key ...]

时间复杂度 O ( n ) O(n) O(n),n为输入的key的个数
redis的很多命令都支持多个key/完成多个操作,目的是为了减少网络IO次数
image.png

del

一次删除一个/多个key,返回删除key的个数

del key [key, ...]

时间复杂度 O ( n ) O(n) O(n),n为输入的key的个数
image.png
若将redis作为缓存,删除个别数据对整体的业务影响不大,因为redis可以从mysql中重新读取数据。但是依然建议,对于删除操作要小心谨慎

expire

给key设置过期时间(单位:秒),存活时间超过这个值就删除key(应用场景如验证码,基于redis实现分布式锁)

expire key seconds
pexpire key 毫秒

时间复杂度 O ( 1 ) O(1) O(1)
返回值为1表示成功,0表示失败
注意:对key设置expire之前,key必须存在,否则将设置失败

ttl

time to live,查看当前key的过期时间,单位:秒
pttl,单位:毫秒

ttl key

时间复杂度 O ( 1 ) O(1) O(1)
返回值:剩余过期时间,-1表示没有关联过期时间(无穷大),-2表示key不存在

redis中key的过期策略

两个策略相结合:

  1. 定期删除:每次抽取一部分key,并保证将这些key全部遍历一遍的时间足够快(单线程)
  2. 惰性删除:时间到了但不删除这个key,用户下次服务这个key时触发删除同时返回nil

然而redis并没有采用定时删除的策略,可能因为引入了定时删除就需要引入多线程
(定时删除策略的实现方式有两种:1. 时间轮 2. 优先级队列)

type

返回key对应value的类型(none, string, set, zset, list, hash)

type key

image.png

redis数据类型的内部实现方式

redis会根据value的具体数值,采用不同的内部类型进行存储。如string有多种内部类型,但是这些内部类型暴露给外部的接口都是相同的

  • string
    • raw:redis实现的最基本字符串
    • int:当value就是整数类型时,redis直接使用int进行存储。int通常也用来实现一些特定功能(如计数)
    • embstr:针对短字符串进行的特殊优化
  • hash
    • hashtable:redis实现的最基本哈希表
    • ziplist:哈希表中,元素比较少时,使用ziplist(压缩列表)节省空间
  • list
    • linkedlist:redis实现的最基本list
    • ziplist
    • 从redis3.2开始,引入quicklist代替linkedlist和ziplist,兼顾两者的优点
  • set
    • hashtable
    • intset:集合中都是整数
  • zset
    • skiplist:跳表,查询效率为 O ( l o g n ) O(logn) O(logn)
    • ziplist

使用

object encoding key

查看key对应value的内部类型
image.png

redis的单线程

redis的单线程并不是说redis内部真的只有一个线程,只是说redis只用一个线程处理所有的命令请求。redis中也有多线程,如网络IO时采用了多线程

为什么redis能够使用单线程?核心业务简单,不消耗cpu资源

若两个客户端“同时”发起一个命令,两个命令相同,都是对某个变量进行自增。虽然两个客户端几乎同时发起命令,但是它们的到达时间存在先后。对于单线程,先到达的先执行,显然不存在线程安全问题

为什么redis比其他数据库效率高?速度快?(和关系型数据库MySQL,Oracle对比)

  1. redis访问内存,其他数据库访问磁盘
  2. redis的核心功能比其他数据库简单。关系型数据库支持了更复杂的功能,比如约束。为了维护这些功能,每次的操作都会导致额外的开销
  3. redis的单线程模型,避免了不必要的线程竞争开销,由于redis的核心功能简单,不消耗cpu资源,采用单线程足以满足需求
  4. redis处理网络IO时,使用epoll这样的IO多路复用机制(在TCP连接中,使用一个线程管理多个socket。因为同一时刻只有少数socket是活跃的,所以可以充分利用等待socket进行IO的时间)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1155651.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

MySQL(4):运算符

算术运算符 算术运算符主要用于数学运算,其可以连接运算符前后的两个数值或表达式,对数值或表达式进行加()、减(-)、乘(*)、除(/)和取模(%&#…

在uni-app中使用ECharts - 配置四种不同的图表

👨‍🦰博主:小猫娃来啦 👨‍🦰文章核心:在uni-app中使用ECharts - 配置四种不同的图表 文章目录 前言安装ECharts插件引入ECharts库创建Charts实例和图表容器配置和渲染图表配置柱状图配置折线图配置饼图配…

详解final, abstract, interface关键字

一.final关键字 1.final关键字介绍 ——final关键字可以去修饰类、方法、属性和局部变量 2.final关键字的作用 1)final修饰类,这个类不能被其他类继承 2)final修饰方法,方法不能被重写 3)final修饰属性,属…

通过shiro框架记录用户登录,登出及浏览器关闭日志

背景: 公司项目之前使用websocket记录用户登录登出日志及浏览器关闭记录用户登出日志,测试发现仍然存在问题, 问题一:当浏览器每次刷新时websocket其实是会断开重新连接的,因此刷新一下就触发记录登出的日志&#xff0…

41.排序练习题(王道2023数据结构第8章综合练习)

试题1(王道8.3.3节综合练习2): 编写双向冒泡排序算法,在正反两个方向交替扫描。即第一趟把关键字最大的元素放在序列的最后面,第二趟把关键字最小的元素放在序列最前面,如此反复。 首先实现冒泡排序&…

FIFO 位宽转换

从8位转32位 module tb_fifo();reg clk,rst; initial beginclk0;forever #4.545 clk~clk; end initial beginrst1;#9.09 rst0; endreg [31:0] cnts; always (posedge clk or posedge rst) beginif(rst)begincnts < 32d0;endelsebegincnts < cnts 1b1;end endreg […

美国白宫发布总统令:鼓励AI以安全、可靠的方式发展

美国华盛顿时间10月30日&#xff0c;美国白宫官网发布了&#xff0c;关于发展安全、可靠和值得信赖的AI&#xff08;人工智能&#xff09;的拜登总统行政令。 白宫表示&#xff0c;该行政令为AI安全和保障制定了新标准&#xff0c;保护了用户的数据隐私&#xff0c;促进公平和…

英语——歌曲篇——only you

《only you》(只有你)赏析 很多人都听过The Platters(派特斯乐队)演唱的《only you》(只有你)这首歌曲&#xff0c;尤其是看过在周星驰和罗家英在《大话西游》里面演绎的"无厘头"版本后。 不过&#xff0c;又有几人知道&#xff0c;这首歌曲原来是经典浪漫影片《罗马…

C语言_常用数据类型地址的理解

常用基本数据类型&#xff1a; #include <stdio.h> #include <stdlib.h> #include <stdint.h>int main(){printf("基本数据类型:\n");printf("char: %d\n", sizeof(char));printf("int: %d\n", sizeof(int));printf("do…

1.6 基本安全设计准则

思维导图&#xff1a; 1.6 基本安全设计准则笔记 目标&#xff1a;理解和遵循一套广泛认可的安全设计准则&#xff0c;以指导保护机制的开发。 主要准则&#xff1a; 机制的经济性&#xff1a;安全机制应设计得简单、短小&#xff0c;便于测试和验证&#xff0c;减少漏洞和降…

linux系统的环境变量-搞清环境变量到底是什么

环境变量 引例环境变量常见的环境变量echoexportenvunsetset 通过代码获取环境变量使用第三个参数获取使用全局变量enviorn获取环境变量通过系统调用获取环境变量 环境变量具有全局属性main函数前两个参数的作用 引例 在linux系统中&#xff0c;我们使用ls命令&#xff0c;直接…

Python 算法高级篇:深度优先搜索和广度优先搜索的高级应用

Python 算法高级篇&#xff1a;深度优先搜索和广度优先搜索的高级应用 引言 1. 深度优先搜索&#xff08; DFS &#xff09;回顾2. 广度优先搜索&#xff08; BFS &#xff09;回顾3. 拓扑排序4. 连通性检测5. 最短路径问题6. 案例分析&#xff1a;社交网络分析7. 总结 引言 深…

剑指 Offer || 084.全排列||

题目 给定一个可包含重复数字的整数集合 nums &#xff0c;按任意顺序 返回它所有不重复的全排列。 示例 1&#xff1a; 输入&#xff1a;nums [1,1,2] 输出&#xff1a; [[1,1,2],[1,2,1],[2,1,1]]示例 2&#xff1a; 输入&#xff1a;nums [1,2,3] 输出&#xff1a;[[1…

【蓝桥杯选拔赛真题07】C++小球自由落体 青少年组蓝桥杯C++选拔赛真题 STEMA比赛真题解析

目录 C/C++小球自由落体 一、题目要求 1、编程实现 2、输入输出 二、算法分析

PostgreSQL在云端:部署、管理和扩展你的数据库

随着云计算技术的迅猛发展&#xff0c;将数据库迁移到云端已经成为许多企业的首选。而在众多数据库管理系统中&#xff0c;PostgreSQL因其稳定性、灵活性和可扩展性而成为了不少企业的首选之一。 部署PostgreSQL在云端 将PostgreSQL部署在云端是一个相对简单的过程。云服务提供…

IMX6ULL——GPIO

本章目的&#xff1a;使用GPIO点亮一个LED灯 1.LED原理 &#xff08;1&#xff09;LED类型&#xff1a;插脚LED&#xff1b;贴片LED。 &#xff08;2&#xff09;LED点亮电路 法一&#xff1a; 法二&#xff1a; 我们本章使用法二&#xff0c;使用IMX6ULL的GPIO引脚输出高低电…

Java架构师软件架构的演化和维护

目录 1 导学2 软件架构演化和定义3 面向对象软件架构演化4 软件架构演化方式的分类5 软件架构演化原则6 软件架构演化评估方法7 大型网站架构演化8 软件架构维护想学习架构师构建流程请跳转:Java架构师系统架构设计 1 导学 2 软件架构演化和定义 软件架构的演化和维护就是对…

2023-2024-1高级语言程序设计第1次月考

7-1-1 计算摄氏温度 给定一个华氏温度F&#xff0c;本题要求编写程序&#xff0c;计算对应的摄氏温度C。计算公式&#xff1a;C5(F−32)/9。题目保证输入与输出均在整型范围内。 输入格式: 输入在一行中给出一个华氏温度。 输出格式: 在一行中按照格式“Celsius C”输出对…

软考系统架构师案例分析知识点整理

系统规划&#xff1a;包括系统项目的提出预可行性分析&#xff1b;系统方案的制定、评价和改进&#xff1b;新旧系统的分析和比较&#xff1b;现有软件、硬件和数据资源的有效利用&#xff1b; 软件架构设计&#xff1a;XML技术&#xff1b;基于架构的软件开发过程&#xff1b;…

【算法通关村第一关】链表经典问题

1.两个链表第一个公共子节点 1.这是一道经典的链表问题&#xff1a;输入两条链表&#xff0c;找出他们的第一个公共节点。 使用集合的方法&#xff1a; public ListNode findFirstCommonNodeBySet(ListNode headA,ListNode headB){Set<ListNode> set new HashSet<&g…