当前位置:Gxlcms > 数据库问题 > Redis NoSql数据库

Redis NoSql数据库

时间:2021-07-01 10:21:17 帮助过:21人阅读

a) 什么是NoSql

b) NoSql的分类

c) 什么是redis

d) Redis应用场景

2、 redis安装(重点)

3、 redis客户端

a) redis自带客户端

b) 图形界面的客户端(了解)

c) Java客户端jedis重点)

4、 Redis数据类型(重点)

a) String类型

b) Map类型

c) List类型

d) Set类型

e) SortedSet

5、 Keys命令(了解)

6、 Redis的持久化方案

a) Rbd方式

b) Aof方式

7、 Redis的主从复制

8、 Redis的集群(重点)

9、 Jedis连接redis集群

 

Redis介绍

2.1 什么是NoSql

为了解决高并发高可用高可扩展大数据存储等一系列问题而产生的数据库解决方案就是NoSql。

 

NoSql,叫非关系型数据库,它的全名Not only sql。它不能替代关系型数据库只能作为关系型数据库的一个良好补充

 

2.2 NoSql的分类

键值(Key-Value)存储数据库

相关产品: Tokyo Cabinet/TyrantRedisVoldemortBerkeley DB

典型应用: 内容缓存,主要用于处理大量数据的高访问负载。 

数据模型: 一系列键值对

优势: 快速查询

劣势: 存储的数据缺少结构化

 

n 列存储数据库

相关产品:Cassandra, HBase, Riak

典型应用:分布式的文件系统

数据模型:以列簇式存储,将同一列数据存在一起

优势:查找速度快,可扩展性强,更容易进行分布式扩展

 劣势:功能相对局限

n 文档型数据库

相关产品:CouchDBMongoDB

典型应用:Web应用(与Key-Value类似,Value是结构化的)

数据模型: 一系列键值对

 优势:数据结构要求不严格

 劣势: 查询性能不高,而且缺乏统一的查询语法

图形(Graph)数据库

相关数据库:Neo4JInfoGridInfinite Graph

典型应用:社交网络

数据模型:图结构

优势:利用图结构相关算法。

劣势:需要对整个图做计算才能得出结果,不容易做分布式的集群方案。

 

2.3 什么是redis

Redis是使用c语言开发的一个高性能键值数据库。Redis可以通过一些键值类型来存储数据。

键值类型

String字符类型

map散列类型

list列表类型

set集合类型

sortedset有序集合类型

 

2.4 redis历史发展

2008年,意大利的一家创业公司Merzia推出了一款基于MySQL的网站实时统计系统LLOOGG,然而没过多久该公司的创始人 Salvatore Sanfilippo便 对MySQL的性能感到失望,于是他决定亲自为LLOOGG量身定做一个数据库,并于2009年开发完成,这个数据库就是Redis。 不过Salvatore Sanfilippo并不满足只将Redis用于LLOOGG这一款产品,而是希望更多的人使用它,于是在同一年Salvatore SanfilippoRedis开源发布,并开始和Redis的另一名主要的代码贡献者Pieter Noordhuis一起继续着Redis的开发,直到今天。

Salvatore Sanfilippo自己也没有想到,短短的几年时间,Redis就拥有了庞大的用户群体。Hacker News2012年发布了一份数据库的使用情况调查,结果显示有近12%的公司在使用Redis。国内如新浪微博、街旁网、知乎网,国外如GitHubStack OverflowFlickr等都是Redis的用户。

VMware公司从2010年开始赞助Redis的开发, Salvatore SanfilippoPieter Noordhuis也分别在3月和5月加入VMware,全职开发Redis

 

2.5 redis的应用场景

缓存(数据查询、短连接、新闻内容、商品内容等等)。(最多使用

分布式集群架构中的session分离。

聊天室的在线好友列表。

任务队列。(秒杀、抢购、12306等等)

应用排行榜。

网站访问统计。

数据过期处理(可以精确到毫秒)

 

redis安装

3.1 redis下载

官网地址:http://redis.io/

下载地址:http://download.redis.io/releases/redis-3.0.0.tar.gz

 

Redis 没有官方的Windows版本,但是微软开源技术团队(Microsoft Open Tech group)开发和维护着这个 Win64 的版本

下载地址:https://github.com/MicrosoftArchive/redis/releases

 

 

 

 

3.2 redis的安装

redis的安装环境可以安装到Windowslinux系统中

Windows安装

安装下载的Redis-x64-3.2.100.msi,或直接解压免安装版

 

 

 

打开 cmd ,跳转到安装目录或解压目录。

 

启动 redis 

 

打开Redis自带的客户端

 

执行相关操作:

 

后端安装服务,可以避免手动启动Redis

redis-server --service-install redis.windows.conf  --service-name Redis

 

卸载Redis 服务

管理员身份运行命令行,输入命令

 

 

查看版本:

 

 

linux安装

第一步安装VMware,并且在VMware中安装centos系统(参考linux教程)。

第二步:将redis的压缩包,上传到linux系统

第三步redis的压缩包进行解压缩

Redis解压缩之后的文件是用c语言写的源码文件

[root@itheima ~]# tar -zxf redis-3.0.0.tar.gz

 

第四步安装c语言环境(安装centos之后,自带c语言环境)

[root@itheima ~]# yum install gcc-c++

第五步编译redis源码

[root@itheima ~]# cd redis-3.0.0

[root@itheima redis-3.0.0]# make

 

第六步:安装redis

[root@itheima redis-3.0.0]# make install PREFIX=/usr/local/redis19

 

第七步查看是否安装成功

 

 

3.3 redis启动

3.3.1 前端启动

前端启动的命令

[root@itheima bin]# ./redis-server

前端启动的关闭

强制关闭:Ctrl+c

正常关闭:[root@itheima bin]# ./redis-cli shutdown

 

启动界面

 

 

前端启动的问题

一旦客户端关闭redis服务也停掉

 

 

3.3.2 后端启动

 

第一步需要将redis解压之后的源码包中的redis.conf文件拷贝到bin目录下

[root@itheima bin]# cp /root/redis-3.0.0/redis.conf ./

 

第二步修改redis.conf文件daemonize改为yes

先要使用vim redis.conf

 

 

第三步使用命令后端启动redis

[root@itheima bin]# ./redis-server redis.conf

第四步查看是否启动成功

 

 

关闭后端启动的方式

 

强制关闭:[root@itheima bin]# kill -9 5071

正常关闭:[root@itheima bin]# ./redis-cli shutdown

 

在项目中建议使用正常关闭

因为redis作为缓存来使用的话将数据存储到内存中如果使用正常关闭则会将内存数据持久化到本地之后再关闭

 

如果是强制关闭则不会进行持久化操作可能会造成部分数据的丢失

 

Redis客户端

4.1 Redis自带的客户端

l 启动

启动客户端命令:[root@itheima bin]# ./redis-cli -h 127.0.0.1 -p 6379

-h:指定访问的redis服务器的ip地址

-p:指定访问的redis服务器的port端口

 

还可以写成:[root@itheima bin]# ./redis-cli

使用默认配置默认的ip127.0.0.1】,默认的port6379

l 关闭

Ctrl+c

127.0.0.1:6379> quit

 

允许远程连接Redis,修改redis.windows.conf文件

 

 

4.2 图形界面客户端

安装文件位置

 

 

安装之后打开如下

 

 

防火墙设置

[root@itheima redis-3.0.0]# vim /etc/sysconfig/iptables

# Firewall configuration written by system-config-firewall

# Manual customization of this file is not recommended.

*filter

:INPUT ACCEPT [0:0]

:FORWARD ACCEPT [0:0]

:OUTPUT ACCEPT [0:0]

-A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT

-A INPUT -p icmp -j ACCEPT

-A INPUT -i lo -j ACCEPT

-A INPUT -m state --state NEW -m tcp -p tcp --dport 22 -j ACCEPT

-A INPUT -m state --state NEW -m tcp -p tcp --dport 3306 -j ACCEPT

-A INPUT -m state --state NEW -m tcp -p tcp --dport 8080 -j ACCEPT

-A INPUT -m state --state NEW -m tcp -p tcp --dport 6379 -j ACCEPT

-A INPUT -j REJECT --reject-with icmp-host-prohibited

-A FORWARD -j REJECT --reject-with icmp-host-prohibited

COMMIT

~                                                                                                     

~                                                                                                     

~                                                                                                     

~                                                                                                     

~                                                                                                     

~                                                                                                     

~                                                                                                     

~                                                                                                     

~                                                                                                     

~                                                                                                     

~                                                                                                     

"/etc/sysconfig/iptables" 16L, 677C 已写入                                          

[root@itheima redis-3.0.0]# service iptables restart

iptables:清除防火墙规则:                                 [确定]

iptables:将链设置为政策 ACCEPTfilter                    [确定]

iptables:正在卸载模块:                                   [确定]

iptables:应用防火墙规则:                                 [确定]

[root@itheima redis-3.0.0]#

 

 

 

 

Redis.conf中的数据库数量的设置

 

 

选择数据库的方式

使用select 加上数据库的下标 就可以选择指定的数据库来使用,下标从0开始

127.0.0.1:6379> select 15

OK

127.0.0.1:6379[15]>

4.3 Jedis客户端

4.3.1 jedis介绍

Redis不仅是使用命令来操作,现在基本上主流的语言都有客户端支持,比如java、C、C#、C++、php、Node.js、Go等。 

在官方网站里列一些Java的客户端,有Jedis、Redisson、Jredis、JDBC-Redis、等其中官方推荐使用Jedis和Redisson。 在企业中用的最多的就是Jedis,下面我们就重点学习下Jedis。 

Jedis同样也是托管在github上,地址:https://github.com/xetorthio/jedis

 

4.3.2 工程搭建

添加jar

 

 

 

4.3.3 单实例连接redis

 

 

4.3.4 使用jedis连接池连接redis服务器

 

 

4.3.5 连接池配置

//Redis服务器IP

 private static String ADDR = "127.0.0.1";

  

//Redis的端口号

 private static int PORT = 6379;

 

 //可用连接实例的最大数目,默认值为8;如果赋值为-1,则表示不限制;如果pool已经分配了maxActivejedis实例,则此时pool的状态为exhausted(耗尽)

 private static int MAX_ACTIVE = 1024;

 

 //控制一个pool最多有多少个状态为idle(空闲的)jedis实例,默认值也是8

 private static int MAX_IDLE = 200;

 

//等待可用连接的最大时间,单位毫秒,默认值为-1,表示永不超时。如果超过等待时间,则直接抛出JedisConnectionException

 private static int MAX_WAIT = 10000;

     

 //borrow一个jedis实例时,是否提前进行validate操作;如果为true,则得到的jedis实例均是可用的;

 private static boolean TEST_ON_BORROW = true;

 private static JedisPool jedisPool = null;

 

  static {

      try {

           JedisPoolConfig config = new JedisPoolConfig();

           config.setMaxTotal(MAX_ACTIVE);

           config.setMaxIdle(MAX_IDLE);

           config.setMaxWaitMillis(MAX_WAIT);

           config.setTestOnBorrow(TEST_ON_BORROW);

           jedisPool = new JedisPool(config, ADDR, PORT);

      } catch (Exception e) {

           e.printStackTrace();

      }

  }

4.3.6 Spring整合jedisPool(自学)

  • 添加springjar
  • 配置spring配置文件applicationContext.xml

<?xml version="1.0" encoding="UTF-8"?>

<beans xmlns="http://www.springframework.org/schema/beans"

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:mvc="http://www.springframework.org/schema/mvc"

xmlns:context="http://www.springframework.org/schema/context"

xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"

xsi:schemaLocation="http://www.springframework.org/schema/beans

http://www.springframework.org/schema/beans/spring-beans-3.2.xsd

http://www.springframework.org/schema/mvc

http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd

http://www.springframework.org/schema/context

http://www.springframework.org/schema/context/spring-context-3.2.xsd

http://www.springframework.org/schema/aop

http://www.springframework.org/schema/aop/spring-aop-3.2.xsd

http://www.springframework.org/schema/tx

http://www.springframework.org/schema/tx/spring-tx-3.2.xsd ">

 

<!-- 连接池配置 -->

<bean id="jedisPoolConfig" class="redis.clients.jedis.JedisPoolConfig">

<!-- 最大连接数 -->

<property name="maxTotal" value="30" />

<!-- 最大空闲连接数 -->

<property name="maxIdle" value="10" />

<!-- 每次释放连接的最大数目 -->

<property name="numTestsPerEvictionRun" value="1024" />

<!-- 释放连接的扫描间隔(毫秒) -->

<property name="timeBetweenEvictionRunsMillis" value="30000" />

<!-- 连接最小空闲时间 -->

<property name="minEvictableIdleTimeMillis" value="1800000" />

<!-- 连接空闲多久后释放, 当空闲时间>该值 且 空闲连接>最大空闲连接数 时直接释放 -->

<property name="softMinEvictableIdleTimeMillis" value="10000" />

<!-- 获取连接时的最大等待毫秒数,小于零:阻塞不确定的时间,默认-1 -->

<property name="maxWaitMillis" value="1500" />

<!-- 在获取连接的时候检查有效性, 默认false -->

<property name="testOnBorrow" value="false" />

<!-- 在空闲时检查有效性, 默认false -->

<property name="testWhileIdle" value="true" />

<!-- 连接耗尽时是否阻塞, false报异常,ture阻塞直到超时, 默认true -->

<property name="blockWhenExhausted" value="false" />

</bean>

 

<!-- redis单机 通过连接池 -->

<bean id="jedisPool" class="redis.clients.jedis.JedisPool"

destroy-method="close">

<constructor-arg name="poolConfig" ref="jedisPoolConfig" />

<constructor-arg name="host" value="192.168.242.130" />

<constructor-arg name="port" value="6379" />

</bean>

</beans>

 

 

  • 测试代码

 

@Test

public void testJedisPool() {

JedisPool pool = (JedisPool) applicationContext.getBean("jedisPool");

Jedis jedis = null;

try {

jedis = pool.getResource();

 

jedis.set("name", "lisi");

String name = jedis.get("name");

System.out.println(name);

} catch (Exception ex) {

ex.printStackTrace();

} finally {

if (jedis != null) {

// 关闭连接

jedis.close();

}

}

}

 

 

 

Redis数据类型

5.1 String

5.1.1 命令

5.1.1.1 赋值

语法:SET key value

127.0.0.1:6379> set test 123

OK

 

5.1.1.2 取值

语法:GET key

127.0.0.1:6379> get test

"123“

5.1.1.3 取值并赋值

语法:GETSET key value

127.0.0.1:6379> getset s2 222

"111"

127.0.0.1:6379> get s2

"222"

 

 

5.1.1.4 设置/获取多个键值 

语法

MSET key value [key value …]

MGET key [key …]

 

127.0.0.1:6379> mset k1 v1 k2 v2 k3 v3

OK

127.0.0.1:6379> get k1

"v1"

127.0.0.1:6379> mget k1 k3

1) "v1"

2) "v3"

 

 

5.1.1.5 删除

语法:DEL key

127.0.0.1:6379> del test

(integer) 1

 

5.1.1.6 数值增减

递增数字

当存储的字符串是整数时,Redis提供了一个实用的命令INCR,其作用是让当前键值递增,并返回递增后的值。

 

语法:INCR key

127.0.0.1:6379> incr num

(integer) 1

127.0.0.1:6379> incr num

(integer) 2

127.0.0.1:6379> incr num

(integer) 3

 

n 增加指定的整数

语法:INCRBY key increment

127.0.0.1:6379> incrby num 2

(integer) 5

127.0.0.1:6379> incrby num 2

(integer) 7

127.0.0.1:6379> incrby num 2

(integer) 9

 

n 递减数值

语法:DECR key

127.0.0.1:6379> decr num

(integer) 9

127.0.0.1:6379> decr num

(integer) 8

 

n 减少指定的整数 

语法:DECRBY key decrement

127.0.0.1:6379> decr num

(integer) 6

127.0.0.1:6379> decr num

(integer) 5

127.0.0.1:6379> decrby num 3

(integer) 2

127.0.0.1:6379> decrby num 3

(integer) -1

 

5.1.1.7 其它命令(自学)

5.1.1.7.1 向尾部追加值 

APPEND的作用是向键值的末尾追加value。如果键不存在则将该键的值设置为value,即相当于 SET key value。返回值是追加后字符串的总长度。 

 

语法APPEND key value

127.0.0.1:6379> set str hello

OK

127.0.0.1:6379> append str " world!"

(integer) 12

127.0.0.1:6379> get str

"hello world!"

 

 

5.1.1.7.2 获取字符串长度 

STRLEN命令返回键值的长度,如果键不存在则返回0。

 

语法STRLEN key

127.0.0.1:6379> strlen str

(integer) 0

127.0.0.1:6379> set str hello

OK

127.0.0.1:6379> strlen str

(integer) 5

 

 

5.1.2 应用

5.1.2.1 自增主键

商品编号、订单号采用string的递增数字特性生成。

 

定义商品编号keyitems:id

192.168.101.3:7003> INCR items:id

(integer) 2

192.168.101.3:7003> INCR items:id

(integer) 3

 

 

 

5.2 Hash

散列类型

5.2.1 使用string的问题

假设有User对象以JSON序列化的形式存储到Redis中,User对象有id,username、password、age、name等属性,存储的过程如下: 

保存、更新: 

User对象 à json(string) à redis

如果在业务上只是更新age属性,其他的属性并不做更新我应该怎么做呢? 如果仍然采用上边的方法在传输、处理时会造成资源浪费,下边讲的hash可以很好的解决这个问题。

 

5.2.2 redis hash介绍

hash叫散列类型,它提供了字段和字段值的映射。字段值只能是字符串类型,不支持散列类型、集合类型等其它类型。如下:

 

 

 

5.2.3 命令

5.2.3.1 赋值

HSET命令不区分插入和更新操作,当执行插入操作时HSET命令返回1,当执行更新操作时返回0。

 

  • 一次只能设置一个字段值

语法HSET key field value

127.0.0.1:6379> hset user username zhangsan

(integer) 1

 

  • 一次可以设置多个字段值

语法HMSET key field value [field value ...]

127.0.0.1:6379> hmset user age 20 username lisi

OK

 

  • 当字段不存在时赋值,类似HSET,区别在于如果字段存在,该命令不执行任何操作

语法HSETNX key field value

127.0.0.1:6379> hsetnx user age 30如果user中没有age字段则设置age值为30,否则不做任何操作

(integer) 0

 

5.2.3.2 取值 

  • 一次只能获取一个字段值

语法HGET key field

127.0.0.1:6379> hget user username

"zhangsan“

 

  • 一次可以获取多个字段值

语法:HMGET key field [field ...]

127.0.0.1:6379> hmget user age username

1) "20"

2) "lisi"

 

  • 获取所有字段值

语法:HGETALL key

127.0.0.1:6379> hgetall user

1) "age"

2) "20"

3) "username"

4) "lisi"

 

 

 

 

5.2.3.3 删除字段

可以删除一个或多个字段,返回值是被删除的字段个数 

 

语法HDEL key field [field ...]

127.0.0.1:6379> hdel user age

(integer) 1

127.0.0.1:6379> hdel user age name

(integer) 0

127.0.0.1:6379> hdel user age username

(integer) 1

 

 

5.2.3.4 增加数字 

语法HINCRBY key field increment

127.0.0.1:6379> hincrby user age 2将用户的年龄加2

(integer) 22

127.0.0.1:6379> hget user age获取用户的年龄

"22“

 

 

5.2.3.5 其它命令(自学)

5.2.3.5.1 判断字段是否存在

语法HEXISTS key field

127.0.0.1:6379> hexists user age查看user中是否有age字段

(integer) 1

127.0.0.1:6379> hexists user name查看user中是否有name字段

(integer) 0

 

 

 

5.2.3.5.2 只获取字段名或字段值

语法

HKEYS key

HVALS key

127.0.0.1:6379> hmset user age 20 name lisi

OK

127.0.0.1:6379> hkeys user

1) "age"

2) "name"

127.0.0.1:6379> hvals user

1) "20"

2) "lisi"

 

 

5.2.3.5.3 获取字段数量 

语法HLEN key

127.0.0.1:6379> hlen user

(integer) 2

 

 

5.2.4 应用

5.2.4.1 存储商品信息

  • 商品字段

【商品id、商品名称、商品描述、商品库存、商品好评】

 

  • 定义商品信息的key

商品1001的信息在 Redis中的key为:[items:1001]

 

  • 存储商品信息

192.168.101.3:7003> HMSET items:1001 id 3 name apple price 999.9

OK

 

  • 获取商品信息

192.168.101.3:7003> HGET items:1001 id

"3"

192.168.101.3:7003> HGETALL items:1001

1) "id"

2) "3"

3) "name"

4) "apple"

5) "price"

6) "999.9"

 

5.3 List

5.3.1 Arraylistlinkedlist的区别

Arraylist是使用数组来存储数据特点:遍历增删慢

Linkedlist是使用双向链表存储数据特点增删快查询慢但是查询链表两端的数据也很快

 

Redislist是采用的是链表结构来存储的,所以对于redislist数据类型的操作,是操作list的两端数据来操作的。

 

 

5.3.2 命令

5.3.2.1 向列表两端增加元素

  • 向列表左边增加元素 

语法LPUSH key value [value ...]  left  push

127.0.0.1:6379> lpush list 1 2 3

(integer) 3

 

  • 向列表右边增加元素 

语法RPUSH key value [value ...]

127.0.0.1:6379> rpush list 4 5 6

(integer) 3

 

5.3.2.2 查看列表 

LRANGE命令是列表类型最常用的命令之一,获取列表中的某一片段,将返回start、stop之间的所有元素(包含两端的元素),索引从0开始。索引可以是负数,如:-1”代表最后边的一个元素

 

语法LRANGE key start stop

127.0.0.1:6379> lrange list 0 2

1) "2"

2) "1"

3) "4"

 

127.0.0.1:6379> lrange list 0 -1

 

5.3.2.3 从列表两端弹出元素 

LPOP命令从列表左边弹出一个元素,会分两步完成:

第一步是将列表左边的元素从列表中移除

第二步是返回被移除的元素值。

 

语法

LPOP key

RPOP key

127.0.0.1:6379> lpop list

"3“

127.0.0.1:6379> rpop list

"6“

 

5.3.2.4 获取列表中元素的个数 

语法LLEN key

127.0.0.1:6379> llen list

(integer) 2

 

5.3.2.5 其它命令(自学)

5.3.2.5.1 删除列表中指定的值 

LREM命令会删除列表中前

人气教程排行