Redis数据库相关知识总结
时间:2023-05-06 12:07:00
Redis总结数据库相关知识
1、NoSQL概述
1.1 为什么用NoSQL
1、单机MySQL的美好年代
20世纪90年代,一个网站的访问量一般都很小,单个数据库很容易处理!
当时静态网页比较多,动态互动网站也不多。
在上述架构下,我们来看看数据存储的瓶颈。
- 当机器放不下数据量的总大小时
- 数据的索引(B Tree)当一台机器的内存无法储存时
- 一个实例不能承受访问量(读写混合)
若满足上述要求 1 or 3个,进化…
DAL:数据库访问层
2、Memcached(缓存) MySQL 垂直拆分(读写分离)
后来,随着访问量的增加,几乎大部分使用MySQL架构网站在数据库中开始出现性能问题,web程序不再只关注功能,而是追求性能。程序猿开始使用大量的缓存技术来缓解数据库的压力,优化数据库的结构和索引。通过文件缓存缓解数据库的压力开始更受欢迎,但当访问量继续增加时,许多web机器不能通过文件缓存共享,大量的小文件缓存也带来了相对较高的IO此时,压力,Memcached就自然的成为一个非常时尚的技术产品。
80%的网站都在阅读,每次查询数据库都很麻烦!所以我们想减轻数据的压力,我们可以使用缓存来确保效率!
发展过程∶优化数据结构和索引----->文件缓存(IO ) -----> Memcached(当时最流行的技术!
3、MySQL主读写分离
由于数据库写入压力的增加,Memcached它只能缓解数据库的读取压力。读写集中在数据库上,使数据库不堪重负。大多数网站开始使用复制技术来实现读写分离,以提高读写性能和读数库的可扩展性,MySQL的master-slave此时模式已成为网站的标配。
4、分表分库 水平拆分 Mysql 集群
在Memcached高速缓存,MySQL主要基于复制、读写分离,此时MySQL由于主库的写作压力开始出现瓶颈,数据量继续飙升,MyISAM使用表锁,在高并发下会出现严重的锁问题,大量的高并发MySQL应用程序开始使用InnoDB引擎代替MyISAM。
与此同时,它开始流行起来分表分库为了缓解写作压力和数据增长的扩展,此时,分表库已成为一种流行的技术,一个流行的面试问题,但也是业界讨论的流行技术问题。也就是在这个时候,MySQL推出不稳定表分区,这也给技术实力一般的公司带来了希望。虽然MySQL推出了MySQL Cluster集群,但性能并不能很好地满足互联网的需求,只是为高可靠性提供了很大的保证。
本质:数据库(读写)
早些年MylSAM:表锁对效率影响很大!高并发会导致严重的锁问题
转战Innodb:行锁
5、MySQL 扩展瓶颈
MySQL数据库还经常存储一些大文本(文件、博客、图片)字段,导致数据库表非常大,数据库恢复非常慢,不容易快速恢复数据库,如1000万4KB大小文本接近40GB如果这些数据可以从大小中提取MySQL省去,MySQL变化很小,关系数据库很强,但它不能很好地处理所有的应用场景,MySQL扩展性差(需要复杂的技术),大数据下IO压力大,表结构难以改变,目前正在使用MySQL开发人员面临的问题。
6.目前,一个基本的互联网项目
7、为什么用NoSQL
今天我们可以通过第三方平台(如:Google,FaceBook等等)可以很容易地访问和捕获数据。用户的个人信息、社交网络、地理位置、用户生成的数据和用户操作日志都翻了一番。如果我们想挖掘这些用户数据,那么SQL数据库已经不适合这些应用了,而NoSQL数据库的发展可以很好地处理这些大数据!
1.2 什么是NoSQL
NoSQL
NoSQL = Not Only SQL,意思:不仅仅是SQL
关系数据库:表格、行、列
随着互联网,非关系数据库非关系数据库Web2.随着0网站的兴起,传统的关系数据库正在应对web2.0网站,特别是超大规模、高并发的社交网络服务类型Web2.0纯动态网站似乎无能为力,暴露了许多难以克服的问题,而非关系数据库由于其自身的特点而发展迅速,Redis发展最快,NoSQL数据库的产生是为了解决各种数据类型的挑战,特别是大数据应用问题,包括超大数据存储。
很多的数据类型用户的个人信息,社交网络,地理位置。这些数据类型的存储不需要一个固定的格式!不需要多月的操作就可以横向扩展的!Map
NoSQL的特点
解耦!
1、易扩展
-
NoSQL 数据库有很多种,但一个共同的特点是去除关系数据库的关系特征。
-
数据之间没有关系,所以很容易扩展,在架构层面带来可扩展的能力。
2.大数据量高性能
-
NoSQL数据库具有非常高的读写性能,尤其是在大数据量下。由于其非关系性,数据库结构简单。
-
一般MySQL使用Query Cache,每次表格更新Cache失败是一种强大的力量Cache,在针对Web2.频繁应用0交互,Cache而且性能不高NoSQL的Cache是记录级,是细粒度Cache,所以NoSQL在这个层面上,性能要高得多。
-
官方记录:Redis 每秒可写8万次,读11万次,NoSQL缓存记录级是一种细粒度缓存,性能相对较高!
3.数据模型多样灵活
- NoSQL无需事先为要存储的数据建立字段,可以随时存储自定义的数据格式,而在关系数据库中,添加或删除字段是一件非常麻烦的事情。如果它是一个非常大的数据量表,那么添加字段就是一场噩梦。
4、传统的RDBMS VS NoSQL
传统的关系数据库 RDBMS - 高度组织化结构化数据 - 结构化查询语言(SQL) - 数据和关系存储在单独的表中 row col - 数据操作语言,数据定义语言 - 严格的一致性 - 基事务
NoSQL
- 代表着不仅仅是SQL
- 没有声明性查询语言
- 没有预定义的模式
- 键值对存储,列存储,文档存储,图形数据库(社交关系)
- 最终一致性,而非ACID属性
- 非结构化和不可预知的数据
- CAP定理和BASE(异地多活)
- 高性能,高可用性 和 可伸缩性
拓展:3V+3高
大数据时代的3V: 主要是对问题的描述
- 海量 Volume
- 多样 Variety
- 实时 Velocity
互联网需求的3高 : 主要是对程序的要求
- 高并发
- 高可用
- 高性能
当下的应用是 NoSQL 和 RDBMS 一起使用
,技术没有高低之分,就看你怎么用!
1.3 NoSQL数据模型简介
案例设计
以一个电商客户,订单,订购,地址模型来对比下关系型数据库和非关系型数据库
传统的关系型数据库你如何设计?
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","billingAddress":{
"city":"beijing"}}],
}
]
}
}
想想关系模型数据库你如何查?如果按照我们新设计的BSon,是不是查询起来很简单。
- 高并发的操作是不太建议有关联查询的,互联网公司用冗余数据来避免关联查询
- 分布式事务是支持不了太多的并发的
1.4 NoSQL四大分类
KV键值:
- 新浪:BerkeleyDB+Redis
- 美团:Redis+Tair
- 阿里、百度:memcache+Redis
文档型数据库(bson格式比较多和json一样):
- CouchDB
- MongoDB
- MongoDB 是一个基于分布式文件存储的数据库。由 C++ 语言编写,主要用来处理大量的文档。
- MongoDB 是一个介于关系数据库和非关系数据库之间的产品,是非关系数据库当中功能最丰富,最像关系数据库的。
列存储数据库:
- Cassandra, HBase
- 分布式文件系统
图关系数据库:
- 它不是放图形的,放的是关系,比如:朋友圈社交网络、广告推荐系统
- 社交网络,推荐系统等。专注于构建关系图谱
- Neo4J,InfoGrid
四者对比
1.5 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) 持久性
持久性是指一旦事务提交后,它所做的修改将会永久的保存在数据库上,即使出现宕机也不会丢失。
CAP(三进二)
- 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 - 满足可用性,分区容忍性的系统,通常可能对一致性要求低一些。
BASE 理论
BASE理论是由eBay架构师提出的。BASE是对CAP中一致性和可用性权衡的结果,其来源于对大规模互联网分布式系统实践的总结,是基于CAP定律逐步演化而来。其核心思想是即使无法做到强一致性,但每个应用都可以根据自身业务特点,采用适当的方式来使系统达到最终一致性。
BASE就是为了解决关系数据库强一致性引起的问题而引起的可用性降低而提出的解决方案。
BASE其实是下面三个术语的缩写:
- 基本可用(Basically Available): 基本可用是指分布式系统在出现故障的时候,允许损失部分可用性,即保证核心可用。电商大促时,为了应对访问量激增,部分用户可能会被引导到降级页面,服务层也可能只提供降级服务。这就是损失部分可用性的体现。
- 软状态(Soft State): 软状态是指允许系统存在中间状态,而该中间状态不会影响系统整体可用性。分布式存储中一般一份数据至少会有三个副本,允许不同节点间副本同步的延时就是软状态的体现。MySQL Replication 的异步复制也是一种体现。
- 最终一致性(Eventual Consistency): 最终一致性是指系统中的所有数据副本经过一定时间后,最终能够达到一致的状态。弱一致性和强一致性相反,最终一致性是弱一致性的一种特殊情况。
它的思想是通过让系统放松对某一时刻数据一致性的要求来换取系统整体伸缩性和性能上改观。为什么这么说呢,缘由就在于大型系统往往由于地域分布和极高性能的要求,不可能采用分布式事务来完成这些指标,要想获得这些指标,我们必须采用另外一种方式来完成,这里BASE就是解决这个问题的办法!
解释:
1、分布式:不同的多台服务器上面部署不同的服务模块(工程),他们之间通过Rpc通信和调用,对外提供服务和组内协作。
2、集群:不同的多台服务器上面部署相同的服务模块,通过分布式调度软件进行统一的调度,对外提供服务和访问。
2、Redis入门
2.1 概述
Redis是什么
Redis:RE
mote DI
ctionary S
erver(远程字典服务器)
是完全开源免费的,用C语言编写的,支持网络、可基于内存亦可持久化的日志型、Key-Value数据库,并提供多种语言的API,redis会周期性的把更新的数据写入磁盘或者把修改操作写入追加的记录文件,并且在此基础上实现了master-slave(主从)同步,遵守BSD协议,基于内存运行,并支持持久化的NoSQL数据库,是当前最热门的NoSQL数据库之一,也被人们称为数据结构服务器。
Redis与其他key-value缓存产品有以下三个特点
- Redis支持数据的持久化,可以将内存中的数据保持在磁盘中,重启的时候可以再次加载进行使用。
- Redis不仅仅支持简单的 key-value 类型的数据,同时还提供list、set、zset、hash等数据结构的存储。
- Redis支持数据的备份,即master-slave模式的数据备份。
Redis能干嘛
-
内存存储和持久化(rdb、aof):内存中是断电即失,redis支持异步将内存中的数据写到硬盘上,同时不影响继续服务
-
效率高,可以用于高速缓存
-
发布、订阅消息系统
-
地图信息分析
-
定时器、计数器(浏览量)
-
…
特性
-
多样的数据类型、基本操作和配置
-
持久化和复制,RDB、AOF
-
事务的控制
-
集群
-
…
常用网站
官网:https://redis.io/
中文网:http://www.redis.cn
2.2 Windows安装
下载地址:https://redis.io/download/
解压到自己电脑的环境目录即可
双击 redis-server.exe 启动即可
通过客户端去访问 redis-cli
# 测试连接
127.0.0.1:6379> ping
PONG
# 基本的set设值
127.0.0.1:6379> set name kuangshen
OK
# 取出存储的值
127.0.0.1:6379> get name
"kuangshen"
重要提示
Window下使用确实简单,但是Redis推荐我们使用Linux去开发使用!帮助文档
2.3 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 命令
yum install gcc-c++
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(可以不用执行)
6、如果make完成后继续执行 make install
make install
7、查看默认安装目录:usr/local/bin
/usr 这是一个非常重要的目录,类似于windows下的Program Files,存放用户的程序
8、拷贝配置文件(备用)
cd /usr/local/bin
ls -l
# 在redis的解压目录下备份redis.conf
mkdir myredis
cp redis.conf myredis # 拷一个备份,养成良好的习惯,我们就修改这个文件
# 修改配置保证可以后台应用
vim redis.conf
-
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进程退出。
9、启动测试一下!
# 【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
2.4 基础知识说明
redis压力测试工具-----Redis-benchmark
Redis-benchmark是官方自带的Redis性能测试工具,可以有效的测试Redis服务的性能。
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 | 通过管道传输 请求 | 1 |
10 | -q | 强制退出 redis。仅显示 query/sec 值 | |
11 | –csv | 以 CSV 格式输出 | |
12 | -l | 生成循环,永久执行测试 | |
13 | -t | 仅运行以逗号分隔的测试命令列表。 | |
14 | -I | Idle 模式。仅打开 N 个 idle 连接并等待。 |
# 测试一: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 次请求
基本数据库常识
默认16个数据库,类似数组下标从零开始,初始默认使用零号库
查看 redis.conf ,里面有默认的配置
databases 16
# Set the number of databases. The default database is DB 0, you can select
# a different one on a per-connection basis using SELECT where
# dbid is a number between 0 and 'databases'-1
databases 16
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
为什么默认端口是6379?粉丝效应!
为什么redis是单线程
我们首先要明白,Redis很快!官方表示,因为Redis是基于内存的操作,CPU不是Redis的性能瓶颈,Redis的瓶颈最有可能是机器内存的大小或者网络带宽。既然单线程容易实现,而且CPU不会成为瓶颈,那就顺理成章地采用单线程的方案了!
Redis采用的是基于内存的采用的是单进程单线程模型的 KV 数据库,由C语言编写,官方提供的数据是可以达到100000+的QPS(每秒内查询次数)。这个数据不比采用单进程多线程的同样基于内存的 K-V数据库 Memcached 差!
Redis为什么这么快?
1)误区1:高性能服务器 一定是多线程来实现的
2)误区2:多线程(CPU上下文切换!) 一定比 单线程 效率高,其实不然!速度:CPU > 内存 > 硬盘
3)redis 核心就是 将所有的数据全都放在内存里,所以说使用单线程去操作效率就是最高的,多线程的本质就是 CPU 模拟出来多个线程的情况,这种模拟出来的情况就有一个代价,就是上下文的切换,对于一个内存的系统来说,它没有上下文的切换就是效率最高的。redis 用 单个CPU 绑定一块内存的数据,然后针对这块内存的数据进行多次读写的时候,都是在一个CPU上完成的,所以它是单线程处理这个事。在内存的情况下,这个方案就是最佳方案。
因为一次CPU上下文的切换大概在 1500ns 左右。从内存中读取 1MB 的连续数据,耗时大约为250us,假设1MB的数据由多个线程读取了1000次,那么就有1000次时间上下文的切换,那么就有1500ns *1000 = 1500us ,我单线程的读完1MB数据才250us ,你光时间上下文的切换就用了1500us了,我还不算你每次读一点数据 的时间。
3、五大数据类型
官方文档
全段翻译:
Redis是一个开放源代码(BSD许可)的内存中数据结构存储,它可以用作数据库
,缓存
和消息代理(消息中间件MQ)
。它支持数据结构,例如字符串,哈希,列表,集合,带范围查询的排序集合,位图,超日志,带有半径查询和流的地理空间索引。Redis具有内置的复制,Lua脚本,LRU驱逐,事务和不同级别的磁盘持久性,并通过Redis Sentinel和Redis Cluster自动分区提供了高可用性。
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
List(列表)
Redis列表是简单的字符串列表,按照插入顺序排序,你可以添加一个元素到列表的头部(左边)或者尾部(右边)。
它的底层实际是个链表 !
Set(集合)
Redis的Set是String类型的无序集合,它是通过HashTable实现的 !
Zset(sorted set:有序集合)
Redis zset 和 set 一样,也是String类型元素的集合,且不允许重复的成员。
不同的是每个元素都会关联一个double类型的分数。
Redis正是通过分数来为集合中的成员进行从小到大的排序,zset的成员是唯一的,但是分数(Score)却可以重复。
3.1 Redis键(key)
# keys * 查看所有的key
127.0.0.1:6379> keys *
(empty list or set)
127.0.0.1:6379> set name mc
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 mc
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 mc
OK
127.0.0.1:6379> get name
"mc"
127.0.0.1:6379> type name
string
3.2 字符串String
单值单Value
常用命令说明:
# =================================================== # 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、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 [范围] # 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 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(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 mykey "redis" # 如果不存在就设置,成功返回1 (integer) 1 127.0.0.1:6379> setnx mykey "mongodb" # 如果存在就设置,失败返回0 (integer) 0 127.0.0.1:6379> get mykey "redis" # =================================================== # mset Mset 命令用于同时设置一个或多个 key-value 对。 # mget Mget 命令返回所有(一个或多个)给定 key 的值。 # 如果给定的 key 里面,有某个 key 不存在,那么这个 key 返回特殊值 nil 。 # msetnx 当所有 key 都成功设置,返回 1 。 # 如果所有给定 key 都设置失败(至少有一个 key 已经存在),那么返回 0 。原子操作 # =================================================== 127.0.0.1:6379> mset k10 v10 k11 v11 k12 v12 OK 127.0.0.1:6379> keys * 1) "k12" 2) "k11" 3) "k10" 127.0.0.1:6379> mget k10 k11 k12 k13 1) "v10" 2) "v11" 3) "v12" 4) (nil) 127.0.0.1:6379> msetnx k10 v10 k15 v15 # 原子性操作! (integer) 0 127.0.0.1:6379> get key15 (nil) # 传统对象缓存 set user:1 value(json数据) # 可以用来缓存对象 mset user:1:name zhangsan user:1:age 2 mget user:1:name user:1:age # =================================================== # getset(先get再set) # =================================================== 127.0.0.1:6379> getset db mongodb # 没有旧值,返回 nil (nil) 127.0.0.1:6379> get db "mongodb" 127.0.0.1:6379> getset db redis # 返回旧值 mongodb "mongodb" 127.0.0.1:6379> get db "redis"