非关系型数据库-NoSQL(Redis)

一、什么是 NoSQL?

  NoSQL(NoSQL = Not Only SQL ),意为不仅仅是SQL,是一项全新的数据库革命性运动,2000 年 前就有人提出,发展至 2009 年趋势越发高涨。它是指运用非关系型的数据存储,相对于铺天盖地的关系型数据库运用,这一概念无疑是一种全新的思维的注入。

  随着互联网 web2.0 网站的兴起,传统的关系数据库在应付 web2.0 网站,特别是超大规模和高并发的 SNS 类型的 web2.0 纯动态网站已经显得力不从心,暴露了很多难以克服的问题,而非关系型的数据库则由于其本身的特点得到了非常迅速的发展。NoSQL 数据库的产生就是为了解决大规模数据集合多重数据种类带来的挑战,尤其是大数据应用难题。


分类举例典型应用场景数据模型优点
键值(key-value)Tokyo Cabinet/Tyrant, Redis, Voldemort, Oracle BDB内容缓存,主要用于处理大量数据的高访问负载,也用于一些日志系统等等。Key 指 向 Value 的键值对,通常用hash table 来实现查找速度快
列存储数据库Cassandra, HBase, Riak分布式的文件系统以列簇式存储,将同一列数据存在一起查找速度快,可扩展性强,更容易进行分布式扩展
文档型数据库CouchDB, MongoDbWeb 应 用 ( 与Key-Value 类似,Value 是结构化的,不同的是数据库能够了解 Value 的内容)Key-Value 对应的键值对,Value 为结构化数据数据结构要求不严格,表结构可变,不需要像关系型数据库一样需要预先定义表结构
图形(Graph)数据库Neo4J, InfoGrid, Infinite Graph社交网络,推荐系统等。专注于构建关系图谱图结构利用图结构相关算法。比如最短路径寻址,N 度关系查找等

二、NoSQL 的特性?

  NoSQL 是 key-value 形式存储,和传统的关系型数据库不一样,不一定遵循传统数据库的一些基本要求,比如说遵循 SQL 标准、ACID 属性、表结构等等。

这类数据库主要有以下特点:

  • 非关系型的、分布式、开源的、水平可扩展的
  • 处理超大量数据
  • 击碎了性能瓶颈
  • 对数据高并发读写
  • 对海量数据的高效率存储和访问
  • 对数据的高扩展性和高可用性

三、什么是 Redis?

  Redis 是一个开源的,先进的 key-value 存储。它通常被称为数据结构服务器,因为键可以包含 string(字符串)、hash(哈希)、list(链表)、set(集合)和 zset(sorted-set–有序集合)。这些数据类型都支持 push/pop、add/remove 及取交集并集和差集及更丰富的操作。

  Redis 和 Memcached 类似,它支持存储的 value 类型相对更多,与 memcached 一样,为了保证效率,数据都是缓存在内存中,区别是 Redis 会周期性的把更新的数据写入磁盘或者把修改操作写入追加的记录文件,并且在此基础上实现了 master-slave(主从)同步

在这里插入图片描述


四、Redis 安装部署

Redis 的官方网站是:http://redis.io

4.1 下载安装包

[root@localhost ~]$ wget http://download.redis.io/releases/redis-2.8.6.tar.gz

4.2 编译安装

[root@localhost ~]$ yum -y install gcc* make 
[root@localhost ~]$ tar –zxvf redis-2.8.6.tar.gz
[root@localhost ~]$ cd redis-2.8.6
[root@localhost ~]$ make
[root@localhost ~]$ make PREFIX=/usr/local/redis install
#指定安装位置,如果没有指定安装位置PREFIX=/usr/local/redis
#则 make install 会把 redis 安装到/usr/local/bin/目录下
[root@localhost ~]$ mkdir /usr/local/redis/etc
[root@localhost ~]$ cp ./redis.conf /usr/local/redis/etc/
#复制 Redis 的配置文件到/usr/local/redis/etc/下,便于管理。

4.3 修改配置文件

[root@localhost ~]$ vim /usr/local/redis/etc/redis.conf
daemonize no #修改为 yes #后台启动

4.4 启动服务

/usr/local/redis/bin/redis-server 配置文件
#必须制定配置文件位置,否则会提示警告

[root@localhost ~]$ 

4.5 客户端连接

/usr/local/redis/bin/redis-cli
	-h IP: 连接指定的 redis 服务器
	-p 6379: 指定 redis 服务器的端口
	-a 密码: 使用密码登录
	-n 数据库号: 指定连接哪个数据库
	--raw: redis 支持存储中文

[root@localhost ~]$ 

4.6 停止 Redis

[root@localhost ~]$ /usr/local/redis/bin/redis-cli shutdown
#或
[root@localhost ~]$ pkill -9 redis

五、Redis 常用命令

都是键值对的形式存在

5.1 string 类型及操作

  string 是最简单的类型,一个 key 对应一个 value,string 类型是二进制安全的。redis 的 string 可以包含任何数据。

5.1.1 set

设置 key 对应的值为 string 类型

例子:添加一个 name=lisi 的键值对应

[root@localhost ~]$ redis-server /usr/local/redis/etc/redis.conf
[root@localhost ~]$ redis-cli
127.0.0.1:6379> set name lisi
OK
5.1.2 setnx

设置 key 对应的值为 string 类型如果 key 已经存在,返回 0,nx 是 not exist 的意思

例子:继续添加一个 name=lisi 的键值对应

127.0.0.1:6379> setnx name lisi
(integer) 0
5.1.3 get

获取 key 对应的 string 值,如果 key 不存在返回 nil
例子:获取name的值

127.0.0.1:6379> get name
"lisi"
127.0.0.1:6379> get age
(nil)
5.1.4 mset & mget

同时设置和获取多个键值对

例子:设置和获取age和sex的值

127.0.0.1:6379> mset age 18 sex man
OK
127.0.0.1:6379> mget age sex
1) "18"
2) "man"

5.1.5 incrby

对 key 的值做加加(指定值)操作,并返回新的值

例子:对age进行加2和减2

127.0.0.1:6379> incrby age 2
(integer) 20
127.0.0.1:6379> incrby age -2
(integer) 18
5.1.6 del

删除一个已创建的 key

例子:删除name的key

127.0.0.1:6379> del name
(integer) 1
127.0.0.1:6379> get name
(nil)

5.2 hash 类型及操作

  Redis hash 是一个 string 类型的 field(字段)和 value 的映射表,它的添加、删除操作都是 0(1)平均;hash 特别适合用于存储对象,相较于将对象的每个字段存成单个 string 类型,将一个对象存储在 hash 类型中会占用更少的内存,并且可以更方便的存取整个对象。
在这里插入图片描述

5.2.1 hset、hmset

hset 表名 字段名 值
hset 表名 字段名 值 字段名 值

设置 hash field 为指定值,如果 key 不存在,则先创建。
hset设置表的一个值,hmset设置表的多个值

例子:为 a1 表创建一个叫 name 字段(key),键值是 lisi,接着创建一个age字段,值是20

127.0.0.1:6379> hset a1 name lisi
(integer) 1
127.0.0.1:6379> hset a1 age 20
(integer) 1

127.0.0.1:6379> hmset a2 name aaa age 18
OK


5.2.1 hget、hmget

意义同上近似,用于返回哈希表中指定字段的值
hget获取表的某一个值,hmget获取表的某多个值

例子:获取name和age的值

127.0.0.1:6379> hget a1 name
"zhangsan"
127.0.0.1:6379> hget a1 age
"20"

127.0.0.1:6379> hmget a1 name age
1) "zhangsan"
2) "20"
5.2.1 hdel

删除制定表中的某一个键值对

例子:删除name字段

127.0.0.1:6379> hdel a1 name
(integer) 1
127.0.0.1:6379> hget a1 name
(nil)
5.2.1 hgetall

列出表中的所有键值对

127.0.0.1:6379> hgetall a1
1) "age"
2) "20"

5.3 list 类型及操作

  list 是一个链表结构,主要功能是 push、pop、获取一个范围内的所有值等等,操作中 key 理解为链表的名字。Redis 的 list 类型其实就是一个每个子元素都是 string 类型的双向链表。我们可以通过push、pop 操作从链表的头部或尾部添加删除元素。
在这里插入图片描述

5.3.1 lpush

在 key 对应 list 的头部添加字符串元素。
lpush 链表名 元素

例子:给zhangsan的链表添加姓名,年龄性别等元素

127.0.0.1:6379> lpush zhangsan zhangsan
(integer) 1
127.0.0.1:6379> lpush zhangsan 18
(integer) 2
127.0.0.1:6379> lpush zhangsan man
(integer) 3

5.3.2 lrange

从指定链表中获取指定范围的元素

例子:获取zhangsan链表的所有元素

127.0.0.1:6379> lrange zhangsan 0 -1
1) "man"
2) "18"
3) "zhangsan"

0 -1:此范围代表全部元素,意为从头到尾

5.3.3 lpush、rpush、lpop、rpop、lrange

详见图示
在这里插入图片描述

5.4 Set 类型及操作

  set 是集合,他是 string 类型的无序集合。Set 是通过 hash table 实现的,对集 、交集、差集。通过这些操作我们可以实现社交网站中的好友推荐和 blog 的 tag 功能。集合不允许有重复值。
在这里插入图片描述

5.4.1 sadd

sadd 集合名 元素
添加一个或多个元素到集合中

例子:添加6个数字到mset集合里

127.0.0.1:6379> sadd mset 1 2 3 4 5 6 
(integer) 6
5.4.2 smembers

获取集合里面所有的元素

例子:获取mset集合的所有元素

127.0.0.1:6379> smembers mset
1) "1"
2) "2"
3) "3"
4) "4"
5) "5"
6) "6"
5.4.3 srem

从集合中删除指定的一个或多个元素

srem 集合名 元素

例子:删除元素 2 4 5

127.0.0.1:6379> srem mset 2 4 5
(integer) 3
127.0.0.1:6379> smembers mset
1) "1"
2) "3"
3) "6"
5.4.4 spop

随机从集合中删除一个元素,并返回
spop 集合名

127.0.0.1:6379> spop mset
"3"
127.0.0.1:6379> smembers mset
1) "1"
2) "6"
5.4.5 scard

获取集合里面的元素个数

scard 集合名

127.0.0.1:6379> scard mset
(integer) 2
5.4.6 sdiff

返回集合 1 与集合 2 的差集。以集合 1 为主

127.0.0.1:6379> sadd mset1 1 2 3 4 
(integer) 4
127.0.0.1:6379> sadd mset2 3 4 5 6 
(integer) 4

127.0.0.1:6379> sdiff mset1 mset2  #mset1为参考对象
1) "1"
2) "2"
127.0.0.1:6379> sdiff mset2 mset1 #mset2为参考对象
1) "5"
2) "6"
5.4.7 sinter

获得两个集合的交集

127.0.0.1:6379> sinter mset1 mset2
1) "3"
2) "4"
5.4.8 sunion

获得指定集合的并集

127.0.0.1:6379> sunion mset1 mset2
1) "1"
2) "2"
3) "3"
4) "4"
5) "5"
6) "6"

5.5 zset 类型及操作

  zset 是 set 的一个升级版本,它在 set 的基础上增加了一个顺序属性,这一属性在添加修改元素的时候可以指定,每次指定后,zset 会自动重新按新的值调整顺序。可以理解为有两列的 mysql 表,一列存的 value,一列存的顺序。操作中 key 理解为 zset 的名字。

在这里插入图片描述

5.5.1 zadd

向一个指定的有序集合中添加元素,每一个元素会对应的有一个分数。你可以指定多个分数/成员组合。如果一个指定的成员已经在对应的有序集合中了,那么其分数就会被更新成最新的,并且该成员会重新调整到正确的位置,以确保集合有序。分数的值必须是一个表示数字的字符串。

zadd 集合名 元素1值 元素1值 元素2属性 元素2属性 元素3值 元素3属性

127.0.0.1:6379> zadd zset 2 zhangsan 1 lisi 1 wangwu
(integer) 3
5.5.2 zrange

返回有序集合中,指定区间内的成员。其中成员按照 score(分数)值从小到大排序。具有相同 score 值的成员按照字典顺序来排列。

127.0.0.1:6379> zadd zset 2 zhangsan 1 lisi 1 wangwu
(integer) 3
127.0.0.1:6379> zrange zset 0 -1 withscores
1) "lisi"
2) "1"
3) "wangwu"
4) "1"
5) "zhangsan"
6) "2"

注: withscores 返回集合中元素的同时,返回其分数(score)

5.5.3 zrem

删除有序集合中指定的值

zrem 集合名 值

127.0.0.1:6379> zrem zset zhangsan
(integer) 1
127.0.0.1:6379> zrange zset 0 -1 withscores
1) "lisi"
2) "1"
3) "wangwu"
4) "1"
5.5.4 zcard

返回有序集合元素的个数

127.0.0.1:6379> zcard zset
(integer) 2

5.6 其他相关命令

命令含义
keys *按照键名查找指定的键。支持通配符(* ?等)redis127.0.0.1:6379>keys h*llo
exists key确认一个键是否存在(1 表示存在)
del key删除一个键(通用)
expire key设置一个键(已存在)的过期时间,如果键已经过期,将会被自动删除
ttl key以秒为单位,返回指定键的剩余有效时间当 key 不存在时,返回 -2 。 当 key 存在但没有设置剩余生存时间时,返回 -1 。否则,以秒为单位,返回 key 的剩余生存时间。
select n选择一个数据库,默认连接的数据库是 0,可以支持共 16 个数据库。在配置文件中,通过databases 16 关键字定义。
move key n将当前数据库的键移动到指定的数据库中,key 键的名字 n(0-16)数据库
type key返回键的类型
dbsize返回当前库中键的数量(所有类型)
save保存所有的数据。很少在生产环境直接使用 SAVE 命令,因为它会阻塞所有的客户端的请求,可以使用 BGSAVE 命令代替. 如果在 BGSAVE 命令的保存数据的子进程发生错误的时,用 SAVE命令保存最新的数据是最后的手段。
info获取服务器的详细信息
config get *获取 redis 服务器配置文件中的参数。支持通配符
flushdb删除当前数据库中所有的数据
flushall删除所有数据库中的所有数据

六、Redis 高级应用

6.1 密码防护

给 redis 服务器设置密码

6.1.1 修改配置文件
[root@localhost ~]$ vim /usr/local/redis/etc/redis.conf
# requirepass foobared
requirepass 123456

6.1.2 重启 redis
[root@localhost ~]$ pkill redis
[root@localhost ~]$ redis-server /usr/local/redis/etc/redis.conf
6.1.3 客户端登录
[root@localhost ~]$ redis-cli -a 123456
#或交互模式下使用【auth 密码】命令
[root@localhost ~]$ redis-cli
127.0.0.1:6379> set name aaa
(error) NOAUTH Authentication required.
127.0.0.1:6379> auth 123456
OK
127.0.0.1:6379> set name aaa
OK

6.2 主从同步

Redis 主从复制过程:

  • 与 master 建立连接,发送 sync 同步命令
  • Master 会启动一个后台进程,将数据库快照保存到文件中,同时 master 主进程会开始收集新的写命令并缓存。
  • 后台完成保存后,就将此文件发送给 slave
  • Slave 将此文件保存到硬盘上
6.2.1 主服务器设置密码

主服务器给自己设置好密码即可(iptables&SELinux 关闭)

[root@localhost ~]$ yum -y install gcc* make 

[root@localhost ~]$ wget http://download.redis.io/releases/redis-2.8.6.tar.gz
[root@localhost ~]$ tar –zxvf redis-2.8.6.tar.gz
[root@localhost ~]$ cd redis-2.8.6
[root@localhost ~]$ make
[root@localhost ~]$ make PREFIX=/usr/local/redis install
#指定安装位置,如果没有指定安装位置PREFIX=/usr/local/redis
#则 make install 会把 redis 安装到/usr/local/bin/目录下

[root@localhost ~]$ mkdir /usr/local/redis/etc
[root@localhost ~]$ cp ./redis.conf /usr/local/redis/etc/
#复制 Redis 的配置文件到/usr/local/redis/etc/下,便于管理。


[root@localhost ~]$ vim /usr/local/redis/etc/redis.conf
# requirepass foobared
requirepass 123456

6.2.2 从服务器修改配置文件,用来连接主服务器

老版本:
  从:
    slaveof #主服务器的 IP 和端口
    masterauth #主服务器的密码(主服务器要设置好密码)

新版本 redis 5.* 以上:
  主:
    找到 bind 127.0.0.1 注释掉,或者修改为本机的 IP 地址(重启)
  从:
    replicaof #主服务器的 IP 和端口
    masterauth #主服务器的密码(主服务器要设置好密码)

源码包复制到从服务器

[root@localhost ~]$  yum -y install openssh-clients* #主从服务都执行一下,安装scp
[root@localhost ~]$ scp -r redis-2.8.6 root@192.168.88.101:/root

从服务器安装redis

[root@localhost ~]$ yum -y install gcc* make
[root@localhost ~]$ cd redis-2.8.6
[root@localhost ~]$ make && make PREFIX=/usr/local/redis install
[root@localhost ~]$ mkdir /usr/local/redis/etc
[root@localhost ~]$ cp ./redis.conf /usr/local/redis/etc/

修改从服务配置文件

[root@localhost ~]$ vim /usr/local/redis/etc/redis.conf
# By default Redis does not run as a daemon. Use 'yes' if you need it.
# Note that Redis will write a pid file in /var/run/redis.pid when daemonized.
daemonize yes
.....
# slaveof <masterip> <masterport>
slaveof 192.168.88.100 6379  #主服务器的ip和端口

# masterauth <master-password>
masterauth 123456    #主服务器密码


6.2.3 重启从服务器,然后测试

可通过 info 命令获取当前服务器身份类型

[root@localhost ~]$ ln -s /usr/local/redis/bin/* /usr/local/bin/ #添加软连接
[root@localhost ~]$ redis-server /usr/local/redis/etc/redis.conf   #启动从服务redis

[root@localhost ~]$ redis-cli
127.0.0.1:6379> keys *
 1) "zhangsan"
 2) "mset"
 3) "mset1"
 4) "a1"
 5) "a2"
 6) "mset2"
 7) "name"
 8) "sex"
 9) "age"
10) "zset"

6.3 数据持久化

Redis 是一个支持持久化的内存数据库,也就是说需要经常将内存中的数据同步到硬盘来保证持久化。

6.3.1 snapshotting(快照)–默认方式RDB

在这里插入图片描述

  Redis会单独创建(fork)一个子进程来进行持久化,会先将数据写入到一个临时文件中,待持久化过程都结束了,再用这个临时文件替换上次持久化好的文件。整个过程中,主进程是不进行任何IO操作的,这就确保了极高的性能如果需要进行大规模数据的恢复,且对于数据恢复的完整性不是非常敏感,那RDB方式要比AOF方式更加的高效。RDB的缺点是最后一次持久化后的数据可能丢失。

  RDB 持久化方式能够在指定的时间间隔能对你的数据进行快照存储。是默认的持久化方式。这种方式是将内存中数据以快照的方式写入到二进制文件中,默认的文件名为 dump.rdb。这种持久化方式被称为快照 snapshotting(快照)。

  • 过了 900 秒并且有 1 个 key 发生了改变 就会触发 save 动作
  • 过了 300 秒并且有 10 个 key 发生了改变 就会触发 save 动作
  • 过了 60 秒并且至少有 10000 个 key 发生了改变 也会触发 save 动作

结论:在 redis.conf 文件中 dir ./定义了数据库文件的存放位置,默认是当前配置文件目录。所以每次重启 redis服务所在的位置不同,将会生成新的 dump.rdb 文件;建议服务器搭建完成时先修改快照文件保存位置。

#创建保存redis的数据库文件存放位置
[root@localhost ~]$ mkdir /usr/local/redis/datadir
[root@localhost ~]$ vim /usr/local/redis/etc/redis.conf
# Note that you must specify a directory here, not a file name.
dir /usr/local/redis/datadir/

重启redis

[root@localhost ~]$ pkill redis
[root@localhost ~]$ redis-server /usr/local/redis/etc/redis.conf
6.3.2 append-only file(缩写 aof)

在这里插入图片描述

   使用 AOF 会让你的 Redis 更加耐久: 你可以使用不同的持久化策略:每次写的时候备份、每秒备份、无备份。使用默认的每秒备份策略,Redis 的性能依然很好(备份是由后台线程进行处理的,主线程会尽力处理客户端请求),一旦出现故障,你最多丢失 1 秒的数据。

以日志的形式来记录每个写操作,将Redis执行过的所有写指令记录下来(读操作不记录),只许追加文件但不可以改写文件,redis启动之初会读取该文件重新构建数据,换言之,redis重启的话就根据日志文件的内容将写指令从前到后执行一次以完成数据的恢复工作、Aof保存的是appendonly.aof文件

打开 redis.conf 配置文件开启 AOF 持久化

[root@localhost ~]$ vim /usr/local/redis/etc/redis.conf
appendonly yes
#默认不使用 AOF 持久化(450 行)将 no 改成 yes。
# appendfsync always
#有写操作,就马上写入磁盘。效率最慢,但是最安全
#appendfsync everysec
#默认,每秒钟写入磁盘一次。
# appendfsync no
#不进行 AOF 备份,将数据交给操作系统处理。最快,最不安全

测试
重启 redis 服务,登录 client 添加一个键值,退出然后 ls 命令查看下是否生成 appendonly.aof。
可以用 cat 查看。

[root@localhost ~]$ pkill redis
[root@localhost ~]$ redis-server /usr/local/redis/etc/redis.conf
[root@localhost ~]$ redis-cli -a 123456
127.0.0.1:6379> set name 123
OK
127.0.0.1:6379> exit

[root@localhost ~]$ cd /usr/local/redis/datadir/
[root@localhost ~]$ ls
appendonly.aof  dump.rdb

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值