狂神说笔记之Redis

1.NoSQL概述

1.1为什么用NoSQL

1.1.1、单机MySQL的美好年代

在90年代,一个网站的访问量一般不大,用单个数据库完全可以轻松应付!
在那个时候,更多的都是静态网页,动态交互类型的网站不多。
上述架构下,我们来看看数据存储的瓶颈是什么?
1. 数据量的总大小,一个机器放不下时
2. 数据的索引(B+ Tree)一个机器的内存放不下时
3. 访问量(读写混合)一个实例不能承受
如果满足了上述 1 or 3个,进化....
DAL:数据库访问层
 

1.1.2、Memcached(缓存)+ MySQL + 垂直拆分 

后来,随着访问量的上升,几乎大部分使用MySQL架构的网站在数据库上都开始出现了性能问题,web程序不再仅仅专注在功能上,同时也在追求性能。程序猿们开始大量使用缓存技术来缓解数据库的压力,优化数据库的结构和索引,开始比较流行的是通过文件缓存来缓解数据库压力,但是当访问量继续增大的时候,多台web机器通过文件缓存不能共享,大量的小文件缓存也带了比较高的IO压力,在这个时候,Memcached就自然的成为一个非常时尚的技术产品。

1.1.3、MySQL主从读写分离

由于数据库的写入压力增加,Memcached只能缓解数据库的读取压力,读写集中在一个数据库上让数据库不堪重负,大部分网站开始使用主从复制技术来达到读写分离,以提高读写性能和读库的可扩展性,MySQL的master-slave模式成为这个时候的网站标配了。

1.1.4、分表分库 + 水平拆分 + Mysql 集群


在Memcached的高速缓存,MySQL的主从复制,读写分离的基础之上,这时MySQL主库的写压力开始出现瓶颈,而数据量的持续猛增,由于MyISAM使用表锁,在高并发下会出现严重的锁问题,大量的高并发MySQL应用开始使用InnoDB引擎代替MyISAM。
同时,开始流行使用分表分库来缓解写压力和数据增长的扩展问题,这个时候,分表分库成了一个热门技术,是面试的热门问题,也是业界讨论的热门技术问题。也就是在这个时候,MySQL推出了还不太稳定的表分区,这也给技术实力一般的公司带来了希望。虽然MySQL推出了MySQL Cluster集群,但性能也不能很好满足互联网的需求,只是在高可靠性上提供了非常大的保证。

1.1.5、MySQL 的扩展性瓶颈

MySQL数据库也经常存储一些大文本的字段,导致数据库表非常的大,在做数据库恢复的时候就导致非常的慢,不容易快速恢复数据库,比如1000万4KB大小的文本就接近40GB的大小,如果能把这些数据从MySQL省去,MySQL将变的非常的小,关系数据库很强大,但是它并不能很好的应付所有的应用场景,MySQL的扩展性差(需要复杂的技术来实现),大数据下IO压力大,表结构更改困难,正是当前使用MySQL的开发人员面临的问题。

1.1.6、今天是什么样子??

1.1.7、为什么用No SQL?

今天我们可以通过第三方平台(如:Google,FaceBook等)可以很容易的访问和抓取数据。用户的个人信息,社交网络,地理位置,用户生成的数据和用户操作日志已经成倍的增加、我们如果要对这些用户数据进行挖掘,那SQL数据库已经不适合这些应用了,而NoSQL数据库的发展却能很好的处理这些大的数据!

1.2什么是Nosql

1.2.1.NoSQL

NoSQL = Not Only Sql (不仅仅是sql)

泛指非关系型数据库

1.2.2.NoSql特点:

解耦!

  • 方便扩展!(数据之间没有关系,很好扩展!)   

       NoSQL 数据库种类繁多,但是一个共同的特点都是去掉关系数据库的关系型特性。数据之间无关系,这样就非常容易扩展,也无形之间,在架构的层面上带来了可扩展的能力。

  • 大数据量高性能!(Redis 一秒写8万次,读取11万次)

      NoSQL数据库都具有非常高的读写性能,尤其是在大数据量下,同样表现优秀。这得益于它的非关系性,数据库的结构简单。

     一般MySQL使用Query Cache,每次表的更新Cache就失效,是一种大力度的Cache,在针对Web2.0的交互频繁应用,

     Cache性能不高,而NoSQL的Cache是记录级的,是一种细粒度的Cache,所以NoSQL在这个层面上来说就要性能高很多了。

     官方记录:Redis 一秒可以写8万次,读11万次!

  •   数据类型是多样型的!(不需要实现设计数据库!随取随用!)

    NoSQL无需事先为要存储的数据建立字段,随时可以存储自定义的数据格式,而在关系数据库里,增删字段是一件非常麻烦的事情。

    如果是非常大数据量的表,增加字段简直就是噩梦。
 

传统RDBMS 和 NoSQL

传统的关系型数据库 RDBMS
- 高度组织化结构化数据
- 结构化查询语言(SQL)
- 数据和关系都存储在单独的表中
- 数据操纵语言,数据定义语言
- 严格的一致性
- 基础事务
No SQL
- 代表着不仅仅是SQL
- 没有声明性查询语言
- 没有预定义的模式
- 键值对存储,列存储,文档存储,图形数据库
- 最终一致性,而非ACID属性
- 非结构化和不可预知的数据
- CAP定理
- 高性能,高可用性 和 可伸缩性

1.2.3.拓展:3V+3高
 

大数据时代的3V : 主要是对问题的描述

  • 海量 Volume
  • 多样 Variety
  • 实时 Velocity

互联网需求的3高 : 主要是对程序的要求

  • 高并发
  • 高可用
  • 高性能

当下的应用是 SQL 和 NoSQL 一起使用,技术没有高低之分,就看你怎么用,对吧!

 1.3阿里巴巴框架演进

1.演变过程:以下图片资料来源:阿里巴巴中文站架构设计实践

2、第五代

第5代架构使命

和我们相关的,多数据源多数据类型的存储问题

1、商品的基本信息
 

名称、价格、出厂日期、生产厂商等
关系型数据库:mysql、oracle目前淘宝在去O化(也即,拿掉Oracle)
注意,淘宝内部用的My SQL是里面的大牛自己改造过的。
为什么去IOE:
2008年,王坚博士加入阿里巴巴,成为首席架构师。把云计算植入阿里IT基因。
2013年5月17日,阿里集团最后一台IBM小机在支付宝下线。这是自2009年“去IOE”战略透露以来,“去
IOE”非常重要的一个节点。“去 IOE”指的是摆脱掉IT部署中原有的IBM小型机、Oracle数据库以及EMC
存储的过度依赖。告别最后一台小机,意味着整个阿里集团尽管还有一些Oracle数据库和EMC存储,但是
IBM小型机已全部被替换。2013年7月10日,淘宝重中之重的广告系统使用的Oracle数据库下线,也是整
个淘宝最后一个 Oracle数据库。这两件事合在一起是阿里巴巴技术发展过程中的一个重要里程碑。

2、商品描述、详情、评价信息(多文字类)

多文字信息描述类,IO读写性能变差
存在文档数据库Mong DB中

3、商品的图片

商品图片展现类
分布式文件系统中
 - 淘宝自己的  TFS
 - Google的   GFS
 - Hadoop的   HDFS

4、商品的关键字
 

搜索引擎,淘宝内用
ISearch:多隆一高兴一个人开发的
所有牛逼的人在牛逼之前,肯定有一段苦逼的岁月,但只要像傻逼一样的坚持,一定终将牛逼

5、商品的波段性的热点高频信息

内存数据库
Tair、Redis、Memcache等

6、商品的交易,价格计算,积分累计!
 

外部系统,外部第三方支付接口
支付宝

大型互联网应用(大数据,高并发,多样数据类型)的难点和解决方案
 

难点:

  • 数据类型的多样性
  • 数据源多样性和变化重构
  • 数据源改造而数据服务平台不需要大面积重构

解决办法:
 

 

 

1.4No SQL数据模型简介

案例设计

以一个电商客户,订单,订购,地址模型来对比下关系型数据库和非关系型数据库
传统的关系型数据库你如何设计?
ER图(1:1/1:N/N:N,主外键等常见)

  • 用户对应多个订单多个地址
  • 每个订单对应每个商品、价格、地址
  • 每个商品对应产品


根据她的信息找到她男朋友的生日就在最近,后台画像已经分析完毕,准备推送广告了,结果她买了一个零食就走了~


90后的程序员真的在一点点的改变生活中的点点滴滴,假设你有幸进入了大厂,你会发现周围的小伙伴都在努力,真的就是那种可以在海底捞吃着吃着饭,突然就掏出笔记本写代码的那种,别人都以为他们是疯子,只有他们自己内心才懂。这才是对技术的痴迷。

NoSQL你如何设计
可以尝试使用BSON。
BSON是一种类json的一种二进制形式的存储格式,简称Binary JSON,它和JSON一样,支持内嵌的文档
对象和数组对象
用BSon画出构建的数据模型
 

{
 "customer":{
   "id":1000,
   "name":"Z3",
   "billingAddress":[{"city":"beijing"}],
   "orders":[
    {
      "id":17,
      "customerId":1000,
      "orderItems":[{"productId":27,"price":77.5,"productName":"thinking in 
java"}],
      "shippingAddress":[{"city":"beijing"}]
      "orderPayment":[{"ccinfo":"111-222-
333","txnid":"asdfadcd334","billing Address":{"city":"beijing"}}],
      }
    ]
  }
}

想想关系模型数据库你如何查?如果按照我们新设计的BSon,是不是查询起来很简单。

  • 高并发的操作是不太建议有关联查询的,互联网公司用冗余数据来避免关联查询
  • 分布式事务是支持不了太多的并发的 

1.5、nosql 四大分类

==KV键值对:==

  • 新浪:BerkeleyDB+redis
  • 美团:Redis + Tair
  • 阿里、百度:Redis + memecache

==文档型数据库(bson格式比较多):==

  • MongoDB
    • MonoDB是一个基于分布式文件存储的数据库,C++编写,主要用来处理大量的文档
    • MonoDB是一个介于关系型数据库和非关系型数据库中中间的产品 (MonoDB是非关系型数据库功能最丰富的,最想关系型数据库)
  • ConthDB

==列存储:==

  • HBase
  • 分布式文件系统

==图形化数据库:==

  • 它不是放图形的,放的是关系比如:朋友圈社交网络、广告推荐系统
  • 社交网络,推荐系统等。专注于构建关系图谱
  • Neo4J, InfoGrid

1.5.1、四者对比

1.6、CAP + BASE

传统的ACID分别是什么?
关系型数据库遵循ACID规则,事务在英文中是transaction,和现实世界中的交易很类似,它有如下四个

  •  A (Atomicity) 原子性
原子性很容易理解,也就是说事务里的所有操作要么全部做完,要么都不做,事务成功的条件是事务
里的所有操作都成功,只要有一个操作失败,整个事务就失败,需要回滚。
比如银行转账,从A账户转100元至B账户,分为两个步骤:
1)从A账户取100元;
2)存入100元至B账户。
这两步要么一起完成,要么一起不完成,如果只完成第一步,第二步失败,钱会莫名其妙少了100
元。
  • C (Consistency) 一致性
事务前后数据的完整性必须保持一致。
  • I (Isolation) 隔离性 
所谓的独立性是指并发的事务之间不会互相影响,如果一个事务要访问的数据正在被另外一个事务修
改,只要另外一个事务未提交,它所访问的数据就不受未提交事务的影响。比如现有有个交易是从A
账户转100元至B账户,在这个交易还未完成的情况下,如果此时B查询自己的账户,是看不到新增加
的100元的
  • D (Durability) 持久性
持久性是指一旦事务提交后,它所做的修改将会永久的保存在数据库上,即使出现宕机也不会丢失。

1.6.1CAP(三进二)

  • C : Consistency(强一致性)

  • A : Availability(可用性)

  • P : Partition tolerance(分区容错性)

CAP理论就是说在分布式存储系统中,最多只能实现上面的两点。
而由于当前的网络硬件肯定会出现延迟丢包等问题,所以分区容错性是我们必须需要实现的。
所以我们只能在一致性和可用性之间进行权衡,没有NoSQL系统能同时保证这三点。
注意:分布式架构的时候必须做出取舍。
一致性和可用性之间取一个平衡。多余大多数web应用,其实并不需要强一致性。
因此牺牲C换取P,这是目前分布式数据库产品的方向
一致性与可用性的决择
对于web2.0网站来说,关系数据库的很多主要特性却往往无用武之地
数据库事务一致性需求
很多web实时系统并不要求严格的数据库事务,对读一致性的要求很低, 有些场合对写一致性要求并不高。允许实现最终一致性。
数据库的写实时性和读实时性需求
对关系数据库来说,插入一条数据之后立刻查询,是肯定可以读出来这条数据的,但是对于很多web应用来说,并不要求这么高的实时性,比方说发一条消息之 后,过几秒乃至十几秒之后,我的订阅者才看
到这条动态是完全可以接受的。对复杂的SQL查询,特别是多表关联查询的需求任何大数据量的web系统,都非常忌讳多个大表的关联查询,以及复杂的数据分析类型的报表查询,特
别是SNS类型的网站,从需求以及产品设计角度,就避免了这种情况的产生。往往更多的只是单表的主键查询,以及单表的简单条件分页查询,SQL的功能被极大的弱化了。
CAP理论的核心是:一个分布式系统不可能同时很好的满足一致性,可用性和分区容错性这三个需求,
最多只能同时较好的满足两个。因此,根据 CAP 原理将 NoSQL 数据库分成了满足 CA 原则、满足 CP 
原则和满足 AP 原则三 大类:
CA - 单点集群,满足一致性,可用性的系统,通常在可扩展性上不太强大。
CP - 满足一致性,分区容忍必的系统,通常性能不是特别高。
AP - 满足可用性,分区容忍性的系统,通常可能对一致性要求低一些。

1.6.2、BASE 理论


BASE理论是由eBay架构师提出的。BASE是对CAP中一致性和可用性权衡的结果,其来源于对大规模互联网分布式系统实践的总结,是基于CAP定律逐步演化而来。其核心思想是即使无法做到强一致性,但每个应用都

可以根据自身业务特点,采用适当的方式来使系统达到最终一致性。


BASE就是为了解决关系数据库强一致性引起的问题而引起的可用性降低而提出的解决方案。


BASE其实是下面三个术语的缩写:

  • 基本可用(Basically Available): 基本可用是指分布式系统在出现故障的时候,允许损失部分可用性,即保证核心可用。电商大促时,为了应对访问量激增,部分用户可能会被引导到降级页面,服务层也可能只提供降级服务。这就是损失部分可用性的体现。
  • 软状态(Soft State): 软状态是指允许系统存在中间状态,而该中间状态不会影响系统整体可用性。分布式存储中一般一份数据至少会有三个副本,允许不同节点间副本同步的延时就是软状态的体现。MySQL Replication 的异步复制也是一种体现。
  • 最终一致性(Eventual Consistency): 最终一致性是指系统中的所有数据副本经过一定时间后,最终能够达到一致的状态。弱一致性和强一致性相反,最终一致性是弱一致性的一种特殊情况。它的思想是通过让系统放松对某一时刻数据一致性的要求来换取系统整体伸缩性和性能上改观。为什么这么说呢,缘由就在于大型系统往往由于地域分布和极高性能的要求,不可能采用分布式事务来完成这些指标,要想获得这些指标,我们必须采用另外一种方式来完成,这里BASE就是解决这个问题的办法!

解释:
1、分布式:不同的多台服务器上面部署不同的服务模块(工程),他们之间通过Rpc通信和调用,对外
提供服务和组内协作。
2、集群:不同的多台服务器上面部署相同的服务模块,通过分布式调度软件进行统一的调度,对外提供
服务和访问。 

2.Redis入门

2.1概述

2.1.1Redis是什么!

Redis(Remote Dictionary Server ),即远程字典服务

是完全开源免费的,用C语言编写的,遵守BSD协议,是一个高性能的(Key/Value)分布式内存数据库,基于内存运行,并支持持久化的NoSQL数据库,是当前最热门的NoSQL数据库之一,也被人们称为数据结构服务器

  • Redis与其他key-value缓存产品有以下三个特点
  • Redis支持数据的持久化,可以将内存中的数据保持在磁盘中,重启的时候可以再次加载进行使用。
  • Redis不仅仅支持简单的 key-value 类型的数据,同时还提供list、set、zset、hash等数据结构的存储。
  • Redis支持数据的备份,即master-slave模式的数据备份。

 Redis能干什么! 

内存储存、持久化、内存中的数据是断电及失、所以说持久化很重要!(rdb、aof)
效率高、可以用于告诉缓存
发布订阅系统
地图信息分析
计时器、计数器、(数据浏览量)

 Redis特性! 

持久化
多样化数据库
集群
事务
……

常用网站

https://redis.io/ 官网
http://www.redis.cn 中文网
 

2.2 安装Redis

2.2.1 Windows安装

windows :https://github.com/dmajkic/redis/downloads 

下载完成解压

启动Redis服务器:

双击运行服务 redis-server.exe

image-20210312191028923

运行成功

再次运行redis客户端 启动 redis-cli.exe

127.0.0.1:6379> ping ----> 测试是否连接成功
PONG
127.0.0.1:6379> set name changan -----> 设置 key value
OK
127.0.0.1:6379> get name ------> 用 key 去寻找 value
"changan"

重要提示
由于企业里面做Redis开发,99%都是Linux版的运用和安装,几乎不会涉及到Windows版,上一步的讲解只是为了知识的完整性,Windows版不作为重点,大家可以自己玩,

企业实战就认一个版:Linux版http://www.redis.cn/topics/introduction

2.2.2 Linux安装

官网下载:  http://download.redis.io/releases/redis-5.0.7.tar.gz

安装步骤
1、下载获得 redis-5.0.7.tar.gz 后将它放到我们Linux的目录下 /opt
2、/opt 目录下,解压命令 :  tar -zxvf redis-5.0.7.tar.gz
3、解压完成后出现文件夹:redis-5.0.7
4、进入目录: cd   redis-5.0.7
5、在 redis-5.0.7 目录下执行 make 命令
 

运行make命令时故意出现的错误解析:(不同系统可能命令不太一样)
1. 安装gcc (gcc是linux下的一个编译程序,是c程序的编译工具)
   能上网: yum install gcc-c++
   版本测试: gcc-v
2. 二次make
3. Jemalloc/jemalloc.h: 没有那个文件或目录
   运行 make distclean 之后再make
4. Redis Test(可以不用执行)

安装完成执行 make

image-20210313130749997

执行完成之后在执行一遍

然后执行 make install

image-20210313130858601

redis 的默认路径在 usr/local/bin目录下面              /usr 这是一个非常重要的目录,类似于windows下的Program Files,存放用户的程序

image-20210313131120947

移动 redis.config 到 本目录下

cd /usr/local/bin
ls -l
# 在redis的解压目录下备份redis.conf
mkdir myredis
cp redis.conf myredis  # 拷一个备份,养成良好的习惯,我们就修改这个文件
# 修改配置保证可以后台应用
vim redis.conf

image-20210313131349900

redis默认不是后台启动,我们需要修改配置文件

找到这个修改为 yes

image-20210313131611230

  • A、redis.conf配置文件中daemonize守护线程,默认是NO。
  • B、daemonize是用来指定redis是否要用守护线程的方式启动。

daemonize 设置yes或者no区别

  • daemonize:yes

       redis采用的是单进程多线程的模式。当redis.conf中选项daemonize设置成yes时,代表开启守护进程模式。在该模式下,redis会在后台运行,并将进程pid号写入至redis.conf选项pidfile设置的文件中,此时redis将一直运行,除非手动kill该进程。

  • daemonize:no

       当daemonize选项设置成no时,当前界面将进入redis的命令行界面,exit强制退出或者关闭连接工具(putty,xshell等)都会导致redis进程退出。
 

启动redis 服务

# 【shell】启动redis服务
[root@192 bin]# cd /usr/local/bin
[root@192 bin]# redis-server /opt/redis-5.0.7/redis.conf
# redis客户端连接===> 观察地址的变化,如果连接ok,是直接连上的,redis默认端口号 6379
[root@192 bin]# redis-cli -p 6379
127.0.0.1:6379> ping
PONG
127.0.0.1:6379> set k1 helloworld
OK
127.0.0.1:6379> get k1
"helloworld"
# 【shell】ps显示系统当前进程信息
[root@192 myredis]# ps -ef|grep redis
root      16005      1  0 04:45 ?        00:00:00 redis-server 
127.0.0.1:6379
root      16031  15692  0 04:47 pts/0    00:00:00 redis-cli -p 6379
root      16107  16076  0 04:51 pts/2    00:00:00 grep --color=auto redis
# 【redis】关闭连接
127.0.0.1:6379> shutdown
not connected> exit
# 【shell】ps显示系统当前进程信息
[root@192 myredis]# ps -ef|grep redis
root      16140  16076  0 04:53 pts/2    00:00:00 grep --color=auto redis

image-20210313131826979

测试连接

image-20210313132042196

查看redis服务信息

image-20210313132339207

关闭redis

2.3基础知识说明

准备工作:开启redis服务,客户端连接


redis压力测试工具-----Redis-benchmark
 

redis性能测试

       
序号 选项 描述 默认值
1 -h 指定服务器主机名 127.0.0.1
2 -p 指定服务器端口 6379
3 -s 指定服务器 socket  
4 -c 指定并发连接数 50
5 -n 指定请求数 10000
6 -d 以字节的形式指定 SET/GET 值的数据大小 2
7 -k 1=keep alive 0=reconnect 1
8 -r SET/GET/INCR 使用随机 key, SADD 使用随机值  
9 -P 通过管道传输 <numreq> 请求 1
10 -q 强制退出 redis。仅显示 query/sec 值  
11 —csv 以 CSV 格式输出  
12 -l 生成循环,永久执行测试  
13 -t 仅运行以逗号分隔的测试命令列表。  
14 -I Idle 模式。仅打开 N 个 idle 连接并等待。

测试 使用 redis-benchmark

测试 :100个并发连接, 100000 请求

# 测试一:100个并发连接,100000个请求,检测host为localhost 端口为6379的redis服务器性
能 
redis-benchmark -h localhost -p 6379 -c 100 -n 100000 
# 测试出来的所有命令只举例一个!
====== SET ======
  100000 requests completed in 1.88 seconds # 对集合写入测试
  100 parallel clients # 每次请求有100个并发客户端
  3 bytes payload # 每次写入3个字节的数据,有效载荷
  keep alive: 1   # 保持一个连接,一台服务器来处理这些请求
17.05% <= 1 milliseconds
97.35% <= 2 milliseconds
99.97% <= 3 milliseconds
100.00% <= 3 milliseconds # 所有请求在 3 毫秒内完成
53248.14 requests per second # 每秒处理 53248.14 次请求

基础知识

 

image-20210318154701720

Redis默认数据库

Redis默认有16个数据库,默认使用第0个

  • select 2 ——> 更换数据库
  • dbsize ——-> 查看数据库大小
  • keys * ———> 查看数据库所有的key
  • flushdb ————> 清空当前数据库
  • flushall ———> 清空所有库

Select命令切换数据库

127.0.0.1:6379> select 7
OK
127.0.0.1:6379[7]>
# 不同的库可以存不同的数据

Dbsize查看当前数据库的key的数量
 

127.0.0.1:6379> select 7
OK
127.0.0.1:6379[7]> DBSIZE
(integer) 0
127.0.0.1:6379[7]> select 0
OK
127.0.0.1:6379> DBSIZE
(integer) 5
127.0.0.1:6379> keys * # 查看具体的key
1) "counter:__rand_int__"
2) "mylist"
3) "k1"
4) "myset:__rand_int__"
5) "key:__rand_int__"

Flushdb:清空当前库
Flushall:清空全部的库
 

127.0.0.1:6379> DBSIZE
(integer) 5
127.0.0.1:6379> FLUSHDB
OK
127.0.0.1:6379> DBSIZE
(integer) 0

为什么redis是单线程


我们首先要明白,Redis很快!官方表示,因为Redis是基于内存的操作,CPU不是Redis的瓶颈,Redis的瓶颈最有可能是机器内存的大小或者

网络带宽。既然单线程容易实现,而且CPU不会成为瓶颈,那就顺理成章地采用单线程的方案了!

Redis采用的是基于内存的采用的是单进程单线程模型的 KV 数据库,由C语言编写,官方提供的数据是可以达到100000+的QPS(每秒内查询次

数)。这个数据不比采用单进程多线程的同样基于内存的 KV 数据库 Memcached 差!

Redis为什么这么快?

1)以前一直有个误区,以为:高性能服务器 一定是多线程来实现的原因很简单因为误区二导致的:多线程 一定比 单线程 效率高,其实不然!
在说这个事前希望大家都能对 CPU 、 内存 、 硬盘的速度都有了解了!
2)redis 核心就是 如果我的数据全都在内存里,我单线程的去操作 就是效率最高的,为什么呢,因为多线程的本质就是 CPU 模拟出来多个线程的情况,这种模拟出来的情况就有一个代价,就是上下文的切换,对于一个内存的系统来说,它没有上下文的切换就是效率最高的。redis 用 单个CPU 绑定一块内存的数据,然后针对这块内存的数据进行多次读写的时候,都是在一个CPU上完成的,所以它是单线程处理这个事。在内存的情况下,这个方案就是最佳方案。
因为一次CPU上下文的切换大概在 1500ns 左右。从内存中读取 1MB 的连续数据,耗时大约为 250us,假设1MB的数据由多个线程读取了1000次,那么就有1000次时间上下文的切换,那么就有1500ns * 1000 = 1500us ,我单线程的读完1MB数据才250us ,你光时间上下文的切换就用了1500us了,我还不算你每次读一点数据 的时间。
 

3. 五种基本数据类型

String (字符串类型)


String是redis最基本的类型,你可以理解成Memcached一模一样的类型,一个key对应一个value。
String类型是二进制安全的,意思是redis的string可以包含任何数据,比如jpg图片或者序列化的对象。
String类型是redis最基本的数据类型,一个redis中字符串value最多可以是512M。

Hash(哈希,类似 Java里的Map)

Redis hash 是一个键值对集合。
Redis hash 是一个String类型的field和value的映射表,hash特别适合用于存储对象。
类似Java里面的Map<String,Object>


List(列表)


Redis列表是简单的字符串列表,按照插入顺序排序,你可以添加一个元素到列表的头部(左边)或者尾
部(右边)。
它的底层实际是个链表 !


Set(集合)

Redis的Set是String类型的无序集合,它是通过HashTable实现的 !
 

Zset(sorted set:有序集合)


Redis zset 和 set 一样,也是String类型元素的集合,且不允许重复的成员。
不同的是每个元素都会关联一个double类型的分数。
Redis正是通过分数来为集合中的成员进行从小到大的排序,zset的成员是唯一的,但是分数(Score)却可以重复。
 

Redis-key

# keys * 查看所有的key
127.0.0.1:6379> keys *
(empty list or set)
127.0.0.1:6379> set name qinjiang
OK
127.0.0.1:6379> keys *
1) "name"
# exists key 的名字,判断某个key是否存在
127.0.0.1:6379> EXISTS name
(integer) 1
127.0.0.1:6379> EXISTS name1
(integer) 0
# move key db ---> 当前库就没有了,被移除了
127.0.0.1:6379> move name 1
(integer) 1
127.0.0.1:6379> keys *
(empty list or set)
# expire key 秒钟:为给定 key 设置生存时间,当 key 过期时(生存时间为 0 ),它会被自动删
除。
# ttl key 查看还有多少秒过期,-1 表示永不过期,-2 表示已过期
127.0.0.1:6379> set name qinjiang
OK
127.0.0.1:6379> EXPIRE name 10
(integer) 1
127.0.0.1:6379> ttl name
(integer) 4
127.0.0.1:6379> ttl name
(integer) 3
127.0.0.1:6379> ttl name
(integer) 2
127.0.0.1:6379> ttl name
(integer) 1
127.0.0.1:6379> ttl name
(integer) -2
127.0.0.1:6379> keys *
(empty list or set)
# type key 查看你的key是什么类型
127.0.0.1:6379> set name qinjiang
OK
127.0.0.1:6379> get name
"qinjiang"
127.0.0.1:6379> type name
string

字符串String

单值单Value
常用命令说明:
set、get、del、append、strlen

# ===================================================
# set、get、del、append、strlen
# ===================================================
127.0.0.1:6379> set key1 value1   # 设置值
OK
127.0.0.1:6379> get key1          # 获得key
"value1"
127.0.0.1:6379> del key1          # 删除key
(integer) 1
127.0.0.1:6379> keys *            # 查看全部的key
(empty list or set)
127.0.0.1:6379> exists key1       # 确保 key1 不存在
(integer) 0
127.0.0.1:6379> append key1 "hello"  # 对不存在的 key 进行 APPEND ,等同于 SET 
key1 "hello"
(integer) 5     # 字符长度
127.0.0.1:6379> APPEND key1 "-2333"  # 对已存在的字符串进行 APPEND
(integer) 10    # 长度从 5 个字符增加到 10 个字符
127.0.0.1:6379> get key1
"hello-2333"
127.0.0.1:6379> STRLEN key1       # # 获取字符串的长度
(integer) 10   

incr、dec

# ===================================================
# incr、decr      一定要是数字才能进行加减,+1 和 -1。
# incrby、decrby  命令将 key 中储存的数字加上指定的增量值。
# ===================================================
127.0.0.1:6379> set views 0       # 设置浏览量为0
OK
127.0.0.1:6379> incr views        # 浏览 + 1
(integer) 1
127.0.0.1:6379> incr views        # 浏览 + 1
(integer) 2
127.0.0.1:6379> decr views        # 浏览 - 1
(integer) 1
127.0.0.1:6379> incrby views 10   # +10
(integer) 11
127.0.0.1:6379> decrby views 10   # -10
(integer) 1

range

# ===================================================
# range [范围]
# getrange 获取指定区间范围内的值,类似between...and的关系,从零到负一表示全部
# ===================================================
127.0.0.1:6379> set key2 abcd123456  # 设置key2的值
OK
127.0.0.1:6379> getrange key2 0 -1   # 获得全部的值
"abcd123456"
127.0.0.1:6379> getrange key2 0 2    # 截取部分字符串
"abc"

setrange 

# ===================================================
# setrange 设置指定区间范围内的值,格式是setrange key值 具体值
# ===================================================
127.0.0.1:6379> get key2
"abcd123456"
127.0.0.1:6379> SETRANGE key2 1 xx   # 替换值
(integer) 10
127.0.0.1:6379> get key2
"axxd123456"

setex

# ===================================================
# setex(set with expire)键秒值
# setnx(set if not exist)
# ===================================================
127.0.0.1:6379> setex key3 60 expire  # 设置过期时间
OK
127.0.0.1:6379> ttl key3  # 查看剩余的时间
(integer) 55
127.0.0.1:6379> setnx
狂神-Redis》视频中的学习笔记是完整的,而且加入了个人的理解和认知。这些笔记工整清晰,适合进行记忆学习。 笔记内容包括以下主题: 1. Nosql概述和为什么要使用Nosql。 2. Redis的基础操作和为什么Redis是单线程且如此快速。 3. Redis的五大基本数据类型,包括String、List、Set、Hash和Zset(有序集合)。 4. Redis的三种特殊类型,包括geospatial(地理位置)、Hyperloglog和Bitmaps。 5. Redis的事务处理和Jedis的使用。 6. Redis与SpringBoot的整合。 7. Redis的配置详解。 8. Redis的持久化方式,包括RDB和AOF(Append only file)以及扩展。 9. Redis的发布订阅功能。 10. Redis的主从复制和哨兵模式。 11. 缓存穿透与雪崩问题的解决方案。 此外,Redis还通过PUBLISH、SUBSCRIBE和PSUBSCRIBE等命令实现了发布和订阅功能。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [狂神-Redis完整版笔记](https://download.csdn.net/download/qq_40986062/79709157)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 33.333333333333336%"] - *2* [Redis学习笔记(狂神)](https://blog.csdn.net/qq_43295483/article/details/119649501)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 33.333333333333336%"] - *3* [【狂神Redis笔记](https://blog.csdn.net/Redemption___/article/details/120799492)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 33.333333333333336%"] [ .reference_list ]
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

好记性,不如烂笔头

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值