目录
[1.5 CAP](#1.5 CAP)
[1.5.1 经典CAP图](#1.5.1 经典CAP图)
[1.5.4 什么是BASE](#1.5.4 什么是BASE)
[2.1 什么是Redis](#2.1 什么是Redis)
[2.2 Redis能干什么](#2.2 Redis能干什么)
[2.3 Redis的特点](#2.3 Redis的特点)
[2.4 Redis与memcached对比](#2.4 Redis与memcached对比)
[2.5 Redis的安装](#2.5 Redis的安装)
[2.6 Docker安装](#2.6 Docker安装)
[三、 基本操作](#三、 基本操作)
[3.1.1 set](#3.1.1 set)
[3.1.3 MSET](#3.1.3 MSET)
[3.2.1 get](#3.2.1 get)
[3.2.2 GETDEL](#3.2.2 GETDEL)
[3.2.3 getrange](#3.2.3 getrange)
[3.2.4 MGET](#3.2.4 MGET)
[3.3 Append](#3.3 Append)
[3.4.1 DESC](#3.4.1 DESC)
[3.4.2 DESCBY](#3.4.2 DESCBY)
[3.5.1 INCR](#3.5.1 INCR)
[3.5.2 INCRBY](#3.5.2 INCRBY)
[3.5.3 INCRBYFLOAT](#3.5.3 INCRBYFLOAT)
[3.6 STRLEN](#3.6 STRLEN)
[3.7 UBSTR](#3.7 UBSTR)
一、NoSQL介绍
1.1什么是NoSQL
NoSQL(Not Only SQL)即不仅仅是SQL,泛指非关系型的数据库,它可以作为关系型数据库的良好补充。随着互联网web2.0网站的兴起,非关系型的数据库现在成了一个极其热门的新领域,非关系数据库产品的发展非常迅速。
1.2为什么会出现NoSQL技术
随着互联网web2.0网站的兴起,传统的关系型数据库在应付web2.0网站,特别是超大规模和高并发的SNS(Social Networking Services 社交网络服务)类型的web2.0纯动态网站已经显得力不从心,暴露了很多难以克服的问题:
(1)High performance - 数据的高并发读写
web2.0网站要根据用户个性化信息来实时生成动态页面和提供动态信息,所以基本上无法使用动态页面静态化技术,因此数据库并发负载非常高,往往要达到每秒上万次读写请求。而关系型数据库应付上万次SQL查询还勉强可以承受,但是应付上万次SQL写数据请求,硬盘IO就已经无法承受了。其实对于普通的BBS网站,往往也存在对高并发写请求的需求,例如网站的实时统计在线用户状态,记录热门帖子的点击次数,投票计数等,因此这是一个相当普遍的需求。
(2)Huge Storage - 海量数据的高效率存储和访问
类似Facebook,twitter,Friendfeed这样的SNS网站,每天用户产生海量的用户动态,如Friendfeed一个月就达到了2.5亿条用户动态。对于关系型数据库而言,在一张2.5亿条记录的表里面进行SQL查询,效率是极其低下乃至不可忍受的。同样对于大型web网站的用户登录系统,如腾讯、阿里、网易等动辄数以亿计的帐号,使用关系型数据库很难应付。
(3)High Scalability & High Availability - 数据库的高扩展和高可用
在基于web的架构当中,数据库是最难进行横向扩展的,当一个应用系统的用户量和访问量与日俱增的时候,你的数据库却没有办法像web server和app server那样简单的通过添加更多的硬件和服务节点来扩展性能和负载能力。对于很多需要提供24小时不间断服务的网站来说,对数据库系统进行升级和扩展是非常痛苦的事情,往往需要停机维护和数据迁移,因此需要数据库具有可扩展和高可用的特性。
总结 : 传统的关系型数据库只能存储结构化数据,对于非结构化的数据支持不够完善。NoSQL数据库的产生就是为了解决大规模数据集合多重数据种类带来的挑战,尤其是大数据应用难题。
1.3NoSQL的类别
- 键值(Key-Value)存储数据库
说明:这一类数据库主要会使用到一个哈希表,这个表中有一个特定的键和一个指针指向特定的数据。
Key/Value模型对于IT系统来说优势在于简单、易部署。
应用:内容缓存,主要用于处理大量数据的高访问负载。
产品:Tokyo Cabinet/Tyrant、Redis、Voldemort、Berkeley DB
优势:快速查询
劣势:存储的数据缺少结构化 - 列存储数据库
说明:这部分数据库通常是用来应对分布式存储的海量数据。键仍然存在,但是它们的特点是**++指向了多个列++****,这些列是由列家族来安排的。**
应用:分布式文件系统
产品:Cassandra,HBase,Riak
优势:查找速度快,可扩展性强,更容易进行分布式扩展
劣势:功能相对局限 - 文档型数据库
说明:该类型的数据模型 是版本化的文档, 半结构化的文档以特定的格式存储,如JSON。 文档型数据库可以看作是键值数据库的升级版,允许之间嵌套键值。而且文档型数据库比键值数据库的查询效率更高。
应用:Web应用
产品:CouchDB,MongoDB
优势:数据结构要求不严格
劣势:查询性能不高,且缺乏统一的查询语法 - 图形(Graph)数据库
说明:图形结构的数据库同其他行列以及刚性结构的SQL数据库不同,它是使用灵活的图形模型,并且能够扩展到多个服务器上。 NoSQL数据库没有标准的查询语言(SQL),因此进行数据库查询需要制定数据模型。 许多NoSQL数据库都有REST格式的数据接口或者查询API。
应用:社交网络
产品: Neo4j,InfoGrid,Infinite Graph
优势:利用图结构相关算法
劣势:需要对整个图做计算才能得出结果,不容易做分布式的集群方案
1.4传统的ACID是什么
关系型数据库遵循ACID规则,事务在英文中是transaction,和现实世界中的交易很类似,它有如下四个特性:
- A (Atomicity) 原子性
指事务里的所有操作要么都成功,要么都失败。事务成功的条件是事务里的所有操作都成功,只要有一个操作失败,整个事务就失败,需要回滚。 - C (Consistency) 一致性
指数据库要一直处于一致的状态,事务的运行不会改变数据库原本的一致性约束。 - I (Isolation) 隔离性
指并发的事务之间不会互相影响,如果一个事务要访问的数据正在被另外一个事务修改,只要另外一个事务未提交,它所访问的数据就不受未提交事务的影响。 - D (Durability) 持久性
是指一旦事务提交后,它所做的修改将会永久的保存在数据库中,即使出现宕机也不会丢失。
1.5 CAP
- Consistency(强一致性)
- Availability(可用性)
-
Partition tolerance(分区容错性)
++CAP理论是指在分布式存储系统中,最多只能实现上面的两点。++ 由于当前的网络硬件存在延迟丢包等问题,所以分区容忍性是我们必须要实现的。所以我们只能在一致性和可用性之间进行权衡,没有NoSQL系统能同时保证这三点。 -
CA传统Oracle数据库
-
AP 大多数网站架构的选择
-
CP Redis、Mongodb(强一致性、分区容错性(例如A数据库中会存放B...的副本))
注意:在做分布式架构的时候必须做出取舍。==一致性和可用性之间取一个平衡==。对于大多数web应用,其实并不需要强一致性。因此牺牲C换取P,这是目前分布式数据库产品的方向。
1.5.1 经典CAP图
CAP理论的核心是: 一个分布式系统不可能同时很好的满足一致性,可用性和分区容错性这三个需求,最多只能同时较好的满足两个。 因此,根据 CAP 原理将 NoSQL 数据库分成了满足 CA 原则、满足 CP 原则和满足 AP 原则三 大类:
- CA - 单点集群,满足一致性,可用性的系统,通常在可扩展性上不太强大。
- CP - 满足一致性,分区容忍必的系统,通常性能不是特别高。
- AP - 满足可用性,分区容忍性的系统,通常可能对一致性要求低一些。
1.5.4 什么是BASE
BASE就是为了解决关系数据库强一致性引起的问题而导致可用性降低而提出的解决方案。BASE其实是下面三个术语的缩写:
基本可用(Basically Available)
软状态(Soft state)
最终一致(Eventually consistent)
它的思想是通过让系统放松对某一时刻数据一致性的要求来换取系统整体伸缩性和性能上改观。为什么这么说呢,缘由就在于大型系统往往由于地域分布和极高性能的要求,不可能采用分布式事务来完成这些指标,要想获得这些指标,我们必须采用另外一种方式来完成,这里BASE就是解决这个问题的办法。
分布式事务的一些方式:...
二、Redis概述
2.1 什么是Redis
Redis(REmote D Ictionary Server 远程字典服务器),是完全开源免费的,用C语言编写的,遵守BSD协议,是一个高性能的(key/value) 分布式(大于一个节点的部署) 内存数据库,基于内存运行( ++优点:存储速度快,缺点:不能持久化++ ),并支持持久化的NoSQL数据库,是当前最热门的NoSQL数据库之一, 也被人们称为数据结构服务器。
Redis是一个开源的高性能键值对(Key-Value)数据库。它通过提供多种键值数据类型来适应不同场景下的存储需求,目前为止Redis支持的键值数据类型如下:
- 字符串类型
- 散列类型
- 列表类型
- 集合类型
- 有序集合类型
学习参考网站: Redis 教程 | 菜鸟教程
2.2 Redis能干什么
- 内存存储和持久化:redis支持异步将内存中的数据写到硬盘上,同时不影响继续服务
- 取最新N个数据的操作,如:可以将最新的10条评论的ID放在Redis的List集合里面
- 模拟类似于HttpSession这种需要设定过期时间的功能
- 发布、订阅消息系统(类似于组播,在一个组中就能收到消息)
- 定时器、计数器
2.3 Redis的特点
- 性能极高:Redis 读的速度是 110000 次 /s,写的速度是 81000 次 /s 。
- 丰富的数据类型:Redis 支持二进制案例的 String,List,Hash,Set及 ZSet 数据类型操作。
- 原子性:Redis 的所有操作都是原子性的,意思就是要么成功执行要么失败完全不执行。单个操作是原子性的。多个操作也支持事务,即原子性,通过 MULTI 和 EXEC 指令包起来。
- 数据持久化:可以将内存中的数据保存在磁盘中,重启的时候可以再次加载进行使用
- 其他特性:Redis 还支持 publish/subscribe 通知,key 过期等特性。
Redis 提供的API支持:C、C++、C#、Clojure、Java、JavaScript、Lua、PHP、Python、Ruby、Go、Scala、Perl等多种语言。
2.4 Redis与memcached对比
- 共同点
无论是Memcached还是Redis底层都是使用C语言编写,都是基于key-value,存储的数据都是在内存中。 - 不同点
Memcached支持的数据类型比较简单(String,Object);Redis 支持的数据类型比较丰富。
Memcached默认一个值的最大存储不能超过1M;Redis一个值的最大存储1G。
Memcached中存储的数据不能持久化,一旦断电数据丢失;Redis中存储的数据可以持久化。
Memcached是多线程,支持并发访问;Redis是单线程,不支持并发访问。
Memcached自身不支持集群环境;Redis从3.0版本之后自身开始提供集群环境支持。、
2.5 Redis的安装
从Redis官网进行下载。 Redis
下面以 redis-6.2.7.tar.gz 版为例,来说明redis的安装与配置。
1、准备安装环境
由于 Redis 是基于 C 语言编写的,因此首先需要安装 Redis 所需要的依赖:
bash
yum install -y gcc tcl gcc-c++ make
2、上传安装文件
将下载好的 redis-6.2.7.tar.gz 安装包上传到虚拟机的任意目录(一般推荐上传到 /usr/local/src目录)。
3、解压安装文件
上传后执行如下命令来进行解压。
bash
tar -zxvf redis-6.2.7.tar.gz
4、进入安装目录
解压完成后,执行如下命令进入解压目录。
bash
cd redis-6.2.7
5、运行编译命令
然后执行如下命令进行编译。
bash
make && make install
说明:如果在编译过程中出现 Jemalloc/jemalloc.h:没有那个文件 没有的错误,在确保 gcc 安装成功后,可执行 make distclean 进行清除后再次安装。
如果没有出错,就会安装成功。默认的安装路径是在 /usr/local/bin 目录下。可以将这个目录配置到环境变量中,这样就可以在任意目录下运行这些命令了。主要的几个命令说明如下:
- redis-server:它是 redis 的服务端启动脚本
- redis-cli:它是 redis 提供的客户端启动脚本
- redis-sentinel:它是 redis 提供的哨兵启动脚本
- redis-benchmark:性能测试工具,可以在自己电脑上运行来查看性能
- redis-check-aof:修复有问题的AOF文件
- redis-check-dump:修复有问题的dump.rdb文件
6、前台启动
执行如下命令来启动 redis。
bash
redis-server
注意:这里直接执行 redis-server 启动的 Redis 服务,是在前台直接运行的(效果如上图),也就是说,执行完该命令后,如果关闭当前会话,则Redis服务也随即关闭,因此这种方式不推荐使用。正常情况下,启动 Redis 服务需要从后台启动。
查看Redis服务:
- ps -ef | grep redis
关闭Redis服务:
- pkill redis-server
- kill 进程号
- 单实例关闭:redis-cli shutdown
- 多实例关闭:redis-cli -p 6379 shutdown
7、后台启动
在 redis 的安装目录中,有一个 redis.conf 文件,我们把这个文件复制到 /etc/目录下:
bash
cp /usr/local/redis/redis.conf /etc/
然后修改 /etc/redis.conf 文件,把 daemonize 值设置为 yes 即可。
bash
vim /etc/redis.conf # 修改daemonize no
保存退出后,执行如下命令来启动服务。
bin>redis-server /etc/redis.conf
8、验证服务
我们可以使用 redis-cli 脚本来连接 redis 服务。
bash
redis-cli -p 6379
然后执行如下命令:
bash
127.0.0.1:6379> ping
PONG
如果能够看到如上信息,表示连接成功。
9、关闭服务
可以执行如下命令来关闭 redis 服务。
bash
redis-cli shutdown
关闭后可以执行如下命令来查看进程是否还存在。
bash
ps -ef | grep redis
注意:也可以进入终端后再关闭:
127.0.0.1:6379> shutdown
10、相关知识
redis 默认的端口号是 6379 ,默认有 16 个数据库,类似数组下标从 0 开始,初始默认使用 0 号数据库。
可以使用 select <dbid> 命令来切换数据库。例如切换到 2 号数据库是 select 2 。
在 redis 中,可以使用 dbsize 命令来查看当前数据库的 key 的数量,也可以使用 flushdb 命令来清空当前数据库中所有数据,还可以使用 flushall 命令来删除所有数据库中的数据。
Redis是单线程+ 多路IO复用技术 。多路复用是指使用一个线程来检查多个文件描述符(Socket)的就绪状态,比如调用select和poll函数,传入多个文件描述符,如果有一个文件描述符就绪,则返回,否则阻塞直到超时。得到就绪状态后进行真正的操作可以在同一个线程里执行,也可以启动线程执行(比如使用线程池)。
2.6 Docker安装
1、拉取镜像
bash
// 拉取最新
docker pull redis
//拉取指定版本
docker pull redis:6.2.7
2、查看镜像
bash
docker images
3、运行容器
bash
docker run --restart=always --log-opt max-size=100m --log-opt max-file=2 -p 6379:6379 --name myredis -v /home/redis/myredis/myredis.conf:/etc/redis/redis.conf -v /home/redis/myredis/data:/data -d redis redis-server /etc/redis/redis.conf --appendonly yes --requirepass 000415
参数说明:
- --restart=always:总是开机启动
- --log:配置日志
- -p 6379:6379:将6379端口挂载出去
- --name:给这个容器取一个名字
- -v:数据卷挂载
- /home/redis/myredis/myredis.conf:/etc/redis/redis.conf:这里是将 liunx 路径下的myredis.conf 和redis下的redis.conf 挂载在一起。
- /home/redis/myredis/data:/data:这个同上
- -d redis:表示后台启动redis
- redis-server /etc/redis/redis.conf:以配置文件启动redis,加载容器内的conf文件,最终找到的是挂载的目录 /etc/redis/redis.conf 也就是liunx下的/home/redis/myredis/myredis.conf
- --appendonly yes:开启redis 持久化
- --requirepass 000415:设置密码 (如果你是通过docker 容器内部连接的话,可设可不设。但是如果想向外开放的话,一定要设置)
4、查看容器
bash
docker ps
5、连接容器
bash
docker exec -it myredis redis-cli
6、测试容器
bash
set name zs
get name
三、 基本操作
3.1.1 set
格式:
bash
SET key value [NX | XX] [GET] [EX seconds | PX milliseconds |
EXAT unix-time-seconds | PXAT unix-time-milliseconds | KEEPTTL]
示例:
bash
127.0.0.1:6379> set mykey1 "hello"
OK
3.1.2set操作的选项
EX seconds -- 设置指定的过期时间,以秒为单位。
PX milliseconds -- 设置指定的过期时间,以毫秒为单位。
EXAT timestamp-seconds -- 设置指定的 Unix 时间,以秒为单位,该时间点时键将过期。
PXAT timestamp-milliseconds -- 设置指定的 Unix 时间,以毫秒为单位,该时间点时键将过期。
NX -- 仅在键不存在时设置键。
XX -- 仅在键已存在时设置键。
KEEPTTL -- 保留与键关联的过期时间。
GET -- 返回键旧的字符串值,如果键不存在则返回 nil。如果键存储的值不是字符串,则返回错误并中止 SET 操作。
示例:
bash
127.0.0.1:6379> set mykey1 "hello"
#为键mykey1设置值"hello"
OK
127.0.0.1:6379> set mykey2 2 EX 5
#为mykey2设置过期时间5秒
OK
127.0.0.1:6379> set mykey2 2 PX 5000
#为mykey2设置过期时间5000毫秒
OK
127.0.0.1:6379> set mykey4 4 EXAT 5
#为mykey4设置unix时间,以秒为单位
OK
127.0.0.1:6379> set mykey5 5 EXAT 5000
#为mykey5设置unix时间,以毫秒为单位
OK
127.0.0.1:6379> set mykey6 6 NX
#为mykey6设置value 当mykey6不存在时创建
OK
127.0.0.1:6379> set mykey7 7 XX
#为mykey7设置value 当mykey7存在时创建(这里很明显创建失败)
(nil)
127.0.0.1:6379> set mykey6 8 GET
"6"
#返回旧键即mykey中的字符串,如果不存在则返回nil,相当于get操作
3.1.3 MSET
格式:
bash
MSET key [key ...]
示例:
bash
127.0.0.1:6379> mset mykey200 200 mykey300 300
#一次性创建多个键值对
OK
3.2.1 get
格式:
bash
GET Key
示例:
bash
127.0.0.1:6379> get mykey1
#查找一个存在的键
"hello"
127.0.0.1:6379> get mykey100
#查找一个不存在的键
(nil)
3.2.2 GETDEL
格式:
bash
GETDEL key
示例:
bash
127.0.0.1:6379> set mykey10 100
#新建一个mykey10键并且赋值
OK
127.0.0.1:6379> getdel mykey10
#找到并且删除该mykey10
"100"
127.0.0.1:6379> get mykey10
#再查看就查不到了
(nil)
3.2.3 getrange
格式:
bash
GETRANGE key start end
示例:
bash
127.0.0.1:6379> getrange mykey1 2 8
#指定查看的键为mykey1 起始位置为2 结束到8
"llo wor"
3.2.4 MGET
格式:
bash
MGET key [key ...]
示例:
bash
127.0.0.1:6379> mget mykey200 mykey300
1) "200"
2) "300"
3.3 Append
格式:
bash
APPEND key value
示例:
bash
127.0.0.1:6379> append mykey1 " world"
#为mykey1后面追加" world"
(integer) 11
127.0.0.1:6379> get mykey1
#查看
"hello world"
3.4.1 DESC
格式:
bash
DECR key
示例:
bash
127.0.0.1:6379> set mykey8 1
OK
127.0.0.1:6379> decr mykey8
(integer) 0
127.0.0.1:6379> decr mykey8
(integer) -1
注意:
(1)desc 能够自减的对象必须是一个数值型数据
(2)desc只能进行自减一的操作
3.4.2 DESCBY
格式:
bash
DECRBY key decrement
示例:
bash
127.0.0.1:6379> decrby mykey8 10
#自减并且指定偏移量为10
(integer) -11
3.5.1 INCR
格式:
bash
INCR key
示例:
bash
127.0.0.1:6379> incr mykey8
(integer) -10
3.5.2 INCRBY
格式:
bash
INCRBY key increment
示例:
bash
127.0.0.1:6379> incrby mykey8 20
(integer) 10
3.5.3 INCRBYFLOAT
格式:
bash
INCRBYFLOAT key increment
示例:
bash
127.0.0.1:6379> incrbyfloat mykey8 0.1
#incrbyfloat 可以使用浮点数自增
"10.1"
3.6 STRLEN
格式:
bash
STRLEN key
示例:
bash
127.0.0.1:6379> strlen mykey1
#获取指定键中的值的长度
(integer) 11
3.7 UBSTR
格式:
bash
SUBSTR key start end
示例:
bash
127.0.0.1:6379> substr mykey1 0 7
#获取指定键子串 起始0 结束到7
"hello wo"