27 Redis 初识

    1. NOSQL简介

NoSQL,泛指非关系型数据库,NoSQL数据库的四大分类:

键值存储数据库:这一类数据库主要会使用到一个哈希表,这个表中有一个特定的键和一个指针指向特定的数据。如Redis,Voldemort,Oracle BDB

列存储数据库:这部分数据库通常是用来对应分布式存储的海量数据,键任然存在,但是它们的特点是指向了多个列。如HBase,Riak。

 

    1. 非关系型数据库的特点
  1. 数据模型比较简单
  2. 需要灵活性更强的IT系统
  3. 对数据库性能要求较高
  4. 不需要高度的数据一致性
  5. 对于给定key,比较容易映射复杂值得环境
    1. Redis简介

是以key-value形式存储,基于内存操作。

 

优点:

对数据高并发读写

对海量数据得高效率存储和访问

对数据的可扩展性和高可用性

扩展性:垂直扩展(在机器上加内存)、水平扩展(在集群中加机器)

高可用性:有多个主节点,当一个主节点挂掉后可以切换到另一个主节点。

数据的可靠性:保证数据不丢失

缺点:

Redis(ACID处理非常简单)

无法做到太复杂的关系数据模型

 

可靠性:

Redis数据都是缓存到内存中的,它可以周期性的把更新的数据写入磁盘或者把修改操作写入追加到文件(RDB)

AOF,可以记录存储日志。

 

主从形式

哨兵形式

集群模式

 

MemCache:

多实例并行执行的,从时间的角度是有优势的,但是管理的复杂度比较高。

Redis:

多实例串行实行的,一个实例一个实例的执行。时间虽然比MemCache耗时一些,但是管理效率高。

 

Redis某种情况下比较慢:为了数据的高可用,必须开启AOF。如果开启AOF,在多线程写的情况下,速度会比较慢,但是读的速度任然很高。如何提高这方面的速度呢?一方面可以多安几台机器来分担写的压力。另一方面可以使用另一种NoSQL数据库做一个技术结合。

 

    1. Redis的安装

 

下载地址:http://redis.io/download

安装步骤:

  1. 首先需要安装gcc,把下载好的redis.tar,gz放到linux/usr/local文件夹下
  2. 进行解压
  3. 进入到redis目录,进行编译make
  4. 进入到src下进行安装make install 验证(查看src目录下,有redis-server,redis-cil即可)
  5. 建立文件夹存放redis命令和配置文件

Make -p  /usr/local/redis/etc

Make -p /usr/local/redis/bin

  1. 把redis下的redis.conf移动到/usr/local/redis/etc下

Cp redis.conf  /usr/local/redis/etc

  1. 把redis/src里的mkreleasehdr.sh、redis-benchmark、redis-check-aof、redis-check-dump、redis-cll、redis-server文件移动到bin下

8 、启动时并指定配置文件:redis-server /usr/local/redis/etc/redis.conf(注意要使用后台启动,所以修改redis.conf路的9daemonize改为yes)

  1. 验证启动是否成功:

Ps -ef|gref redis 查看否有redis服务或者查看端口:netstat -tunpl | grep 6379

进入redis客户端 /redic-cli 退出哭护短quit

退出redis服务:(1) pkill redis-server

  1. kill进程号
  2. /usr/local/redis/bin/redis-cil shutdown

 

2.1 String类型

 

Redis一共分为五种数据类型:String、Hash、List、Set、ZSet

String类型是包含很多种类型的特殊类型,并且是二进制安全的,比如序列化的对象进行存储,比如一张图片进行二进制存储,比如一个简单的字符串,数值等等。

Set和get方法:

设置值:set name name

取值:get name

删除值:del name

使用setnx(not exist)

name如果不存在进行设置,存在就不需要进行设置了,返回0

使用setex(expired)

Setex color(key)  10  red(value) 设置color的有效期为10秒,10秒后返回nil(在redis里nil表示空)

使用setrange替换字符串

Set email [email protected]

Setrange email 10 ww ( 10 表示从第几位离开时替换,后面跟上替换的字符串)

 

使用一次性设置多个和获取多个值的mset、mget

Mset key1 value1 key2 value2

Mget key1 key2

 

` 一次性设置和取值的getset方法

Set key value1

Getset key value2 返回旧值并设置新的方法

 

Incr和decr方法:对某一个值进行递增和递减

Incrby和decrby方法:对某个值进行指定长度的递增和递减

Append [name]方法:字符串追加方法

Strlen [name]方法:获取字符串的长度

 

 

2.2 Hash类型

Hash类型是String类型的field和value的映射表,或者说一个String集合。它特别适合存储对象,相比较而言,将一个对象类型存储在Hash类型里面要比存储在String类型里占用更少的内存空间。并方便存取整个对象。

形如:hset myhash field1 hello(含义是hset是hash集合,myhash是集合名字,field1是字段名字 hello为其值) 使用hget myhash field1获取内容,也可以存储多个值hmset进行批量存储多个键值对:hmset myhash sex nan addr beijing,

也可以使用hmget及进行批量获取多个键值对。

 

Hincyby和hdecrby:集合递增和递减

Hexists:是否存在key 如果存在就返回  不存在返回0

Hlen :返回hash集合里面的所有键值数量

Hdel :删除执行hash的field

Hkeys :返回hash里面的所有字段

Hvals :返回hash的所有value

Hgettall :返回hash里面所有的keu和value

 

 

2.3 List类型

List类型是一个链表结构的集合,其主要功能有push、pop、获取元素等。更详细的说,List类型是一个双端链表的结构,我们可以通过相关的操作进行集合的头部或者尾部添加删除元素,list的设计非常简单精巧,即可以作为栈,又可以作为队列。满足绝大多数需求。

lpush方法:从头部加入元素,先进后出

形如:lpush list1 “hello”  lpush list1 “world”

Lrange list1 0 -1 (表示从头取到末尾)

rpush方法: 从尾部加入元素,先进先出

形如:rpush list1 “hello” rpush list1 “world”

Lrange list1 0 -1

 

linsert方法:插入元素

形如:linsert list1 before [集合的元素] [插入的元素]

 

lset方法:将指定下标的元素替换掉

Lset  list1  0  “a” (用“a”替换下标是0的)

 

lrem方法:删除元素  返回删除的个数

Lrem list1 2 “a”   (移除两个a)

 

ltrim方法:保留指定key的值范围内的数据

Ltrim  list1 1 3  (保留小标从1到3的数据)

 

lpop方法:从list的头部删除元素,并返回删除元素

rpop方法:从list的尾部删除元素,并返回删除元素

 

 

 

 

2.4 set类型和 zset类型

Set集合是String类型的无序集合,set是通过hashtable实现的,对集合我们可以取交集、并集、差集。

 

sadd方法:向名称为key的set中添加元素

小结:set集合不允许重复元素  smembers查看set集合的元素

 

srem方法:删除set集合元素

 

spop方法:随机返回删除的key

 

sdiff方法:返回两个集合的不同元素(哪个集合在前面就以哪个集合为标准)

 

sdiffstore方法:将返回的不同元素存储到另一个集合里

小结:这里是把set1和set2的不同元素(以set1为标准)存储到set3集合。

 

sinter方法:返回集合的交集

Sinter set1 set 2

sinterstore方法:返回交集结果,存入set3中

Sinterstore set3 set1 set2

 

sunion方法:取并集

Sunion set1 set2

sunionstore:取并集,存入set3中

Sunionstore set3 set1 set2

 

smove方法:从一个set集合移动到另一个set集合里

Smove set1 set2

 

scard方法:查看集合里元素个数

sismember方法:判断某元素是否为集合中的元素

小结:返回1代表是集合中的元素,0代表不是

 

srandmember方法:随机返回一个元素

 

 

zadd方法 :  向有序集合中添加一个元素,该元素如果存在,则更新顺序

小结:在重复插入的时候会根据顺序属性更新

例:zadd  zset1  1   one  (向key为zset1的有序集合中添加编号为1的值是one,有序集合是按着给出的编号给排序的)

 

zrange方法 : 查看zset中的元素

例:zrange zset1 0 -1 withscores (withscores的意思是携带编号输出)

zrem方法:删除名称为key的zset中的元素member

zincrby方法:以指定值取自动递增或者减少

zrangebyscore方法:找到指定区间范围的数据进行返回

zremrangebyrank方法:删除1到1(只删除索引1)

zremrangebyscore方法:删除指定序号

 

zrank方法:返回排序索引 从小到大(升序排序之后再找索引)

注意一个是顺序号 一个是索引zrank返回的是索引

zrevrank 返回排序索引 从大到小 (降序排序之后再找索引)

zrangebyscore  zset1  2  3  withscores找到指定区间范围的数据进行返回

 

zcard返回集合里所有元素的个数

zcount返回集合中score在给定区间中的数量

 

 

3.1 Redis高级命令及特性

返回满足的所有键keys *(可以模糊匹配)

exists是否存在指定的key

expire设置某个key的过期时间,使用ttl查看剩余时间

persist取消过期时间

select选择数据库,数据库为0到15(一共16个数据库)默认进入的是0数据库

 

这16个库是逻辑上的划分,而不是物理上的划分。

可以通过不同的数据库存放不同类型的数据。

 

move [key] [数据库下标] 将当前数据中的key转移到其他数据库中

randomkey随机返回数据库里的一个key

rename重命名key

 

 

echo 打印命令

dbsize 查看数据库的key数量

Info 获取数据库信息

config get 实时传输收到的请求(返回相关的配置信息)

config  get  *  返回所有配置

flushdb 清空当前数据库,flushall 清空所有数据库

 

 

 

 

3.2 Redis的安全性

因为redis速度相当快,所以再一台比较好的服务器下,一个外部用户在一秒内可以进行15W次的密码尝试,这意味你需要设定非常强大的密码来防止暴力破解。

Vi编辑 redis.conf文件 找到下面进行保存修改

#requirepass foobared

requirepass ****

重新启动服务器pkill redis-server

再次进入127.0.0.1:6379> keys *

(error)NOAUTH Authentication required

会发现没有权限进行查询127.0.0.1:6379> auth ****

OK 输入密码则成功进入

每次进入的时候都要输入密码,还有种简单方式:

/usr/loacl/redif/bin/redis-cli -a ****

 

3.3 主从复制

主从复制:

1、Master(主服务)可以拥有多个slave(从服务)

2、多个slave可以连接同一个master外,还可以连接到其他的slave

3、主从复制不会阻塞master在同步数据时master可以继续处理client请求

4、提供系统的伸缩性

 

主从复制过程:

  1. slave与master建立连接,发送sync同步命令
  2. Master会开启一个后台进程,将数据库快照保存到文件中,同时master主进程会开始收集新的写命令并缓存
  3. 后台完成保存后,就将文件发送给slave
  4. Slave将此文件保存到硬盘上

主从复制配置:

clone服务器之后修改slave的IP地址

修改配置文件:redis.conf

第一步:slaveof

第二步:masterauth

使用info查看role角色即可知道是主服务或从服务

 

scp -r 本机文件  远程机目录  (远程复制文件)

yum install gcc  (安装gcc)

 

集群的话至少需要三个节点,哨兵不需要

从服务器不支持写

 

3.4 哨兵

有了主从复制的实现以后,我们如果想对主从服务器进行监控,那么在redis2.6以后提供了一个“哨兵”的机制,在2.6版本中的哨兵为1.0版本,并不稳定,会出现各种各样的问题。在2.8以后版本哨兵功能才稳定起来。

顾名思义,哨兵放入含义就是监控Redis系统的运行状况。其主要功能有两点:

  1. 监控主数据库和从数据库是否正常运行。
  2. 主数据库出现故障时,可以自动将从数据库转换为主数据库,实现自动切换。(体现高可用,没有单点
  3. 实现步骤:在其中一台从服务器配置sentinel.conf
  1. copy文件sentinel.conf到/usr/local/redis/etc/中
  2. 修改sentinel.conf

Sentinel monitor mymaster 192.168.x.x 6379 x #名称、ip、端口号、投票选举次数

Sentinel down-after-millisenconds mymaster 5000 #默认1s检测一次,这里配置超时5000毫秒为宕机

Sentinel failover-timeout master 9000000

Sentinel parallel-syncs mymaster 2

Sentinel can-failover mymaster yes

 

  1. 启动sentinel哨兵

/usr/local/redis/bin/redis-server /usr/loacl/redis/etc/sentinel.conf --sentinel &  (“&” 表示后台启动)

 

  1. 查看sentinel哨兵

/usr/local/redis/bin/redis-cli -h 192.168.x.x -p 26379 info Sentinel

  1. 关闭主服务器查看集群信息

/usr/local/redis/bin/redis-cli -h 192.168.x.x -p 26379 shutdown

 

哨兵可以配置多个

 

 

 

4.1 Redis简单事务

Redis的事务非常简单,使用方法如下:

首先是使用multi方法打开事务,然后进行设置,这时设置的数据都会放入队列里进行保存,最后使用exec执行,把数据一次存储到redis中,使用discard方法取消事务,即事务回滚。

缺点:当事务提交后,有失败的操作的时候是不支持回滚的,即没有一致性

 

 

 

4.2 持久化机制

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

  1. snapshotting(快照)默认方式,内存中以快照的方式写入到二进制文件中,默认为dump.rdb。可以通过配置设置自动做快照持久化方式。我们可以配置redis在n秒内,如果超过m个key做修改,就自动做快照。

snapshotting设置:

Save 900 1  #900秒内如果超过1个key被修改 则发起快照保存

Save 300 10  #300秒内如果超过10个key被修改,则发起快照保存

Save 60 10000

 

  1. append-only file (缩写aof)的方式(有点类似于oracle日志)由于快照方式是在一定的时间间隔做一次,所以可能发生redis意外down的情况就会丢失最后一次快照后的所有修改的数据、aof比快照方式有更好的持久化性,是由于在使用aof时,redis会将每一个收到的写命令都通过write的函数追加到命令中,当redis重新启动时会重新执行文件中保存的写命令来在内存中重建这个数据库的内容,这个文件在Bin目录下,appendonly.aof。aof不是立即写到硬盘上,可以通过配置文件修改强制写到硬盘上。

aof设置:

appendonly yes   #启动aof持久化方式有三种修改方式

#appendfsync always  #收到写命令就立即写入到磁盘,效率最慢,但是保证完全的持久化

#appendfsync everysec #每秒中写入磁盘一次,在性能和持久化方面做了很好的折中

#appendfdync no  #完全依赖os  性能最好  持久化没保证

 

4.3 发布与订阅消息

redis提供了简单的发布订阅的功能

使用subscribe [频道] 进行订阅监听

使用publish [频道] [发布内容] 进行发布消息广播

 

5.1 Java & Redis

Jedis就是redis支持java的第三方类库,我们可以使用Jedis类库操作redis数据库。大体上在3.0之前,我们使用Jedis操作redis数据库的api比较全面,但是目前java第三方可用库更新比较慢,不太全面目前最新的jedis2.7版本支持集群操作,不过有些方法也不支持。

 

  1. 使用Jedis连接Redis数据库,操作和Redis脚本一样:

Jedis jedis = new Jedis("172.7.xx.xx",6379);

  1. 怎样按条件查询Redis数据库?

在往Redis数据库中存取数据(使用map)的时候,事先按类别保存到set中。这样直接按需求查找set,通过set找到map的key,从而得到想要的数据。

  1. Redis中的map不能存储Object类型怎么办?

先将object转换为json格式,进行保存

 

 

你可能感兴趣的:(#,T-JAVA)