您的位置:首页 > 数据库 > Redis

redis学习笔记

2017-10-03 09:32 295 查看

一.概述

首先提一下下NoSQL的概念,应读做“嗯欧SQL”,而不是“肉SQL”,等价于Not Only SQL。非关系型数据库(NoSQL)的产生于WEB2.0,传统的web1.0是不可以进行互动的,到了web2.0是可以进行互动的,比如新浪微博。。。传统关系型数据库在应对web2.0(尤其是超大规模和高并发的SNS类型)暴露出很大的问题,比如

1.高并发读写问题,

2.海量数据的高效率存储和访问,

3.高可扩展性和高可用性。

常见的NOSQL有redis、mongoDB等;NoSQL所具备的优势有:

1.易扩展性

2.灵活的数据模型

3.大数据量,高性能

4.高可用

NoSQL数据库的分类主要有四类:

1.键值存储(优点:快速查询;劣势:数据缺少结构化;如redis)

2.列存储(优点:查找快,可扩展性强;劣势:功能局限。如HBase)

3.文档数据库(优点:数据结构的要求不是特别严格;劣势:查询的速度不高,缺少统一的语法;如mongoDB、CounchDB)

4.图形数据库(优点:利用图做数据结构;劣势:需要对图做计算,不容易作分路式集群方案;如InfoGrid)

二.redis常用操作(位置/user/local,启动进入redis的目录中,bin/redis-server redis.conf)

1.redis所支持的数据类型:redis是高性能键值对数据困,支持的数据类型有字符串(String)、字符串列表(list)、有序集合(sorted set)、哈希(hash)、字符串集合(set)

2.redis的应用场景:缓存、任务队列、应用排行榜、网站统计访问、数据过期处理、分布式集群架构中的session分离。

通用操作:

1.获取所有的key–keys *

2.获取所有以my开头的key–keys my?

3.删除多个key–del + “key1” + “key2”…..

4.判断某个key是否存在(存在返回1,不存在返回0)–exists + “key”

5.获取指定key–get + “key”

6.重命名指定的key–rename + “oldname” + “newname”

7.设置过期时间(单位为秒)–expire + “key” + “时间长度”

8.查看所剩的生命时长(相对设置的生命周期而言,若没有设置过期时间返回-1)–ttl + “key”

9.查看指定key的类型–type + “key”

String类型的操作:

1.赋值–set + “key” + “value”

2.取值–get + “key”

3.先获取再赋值(输出原始值,然后重新赋值)–getset + “key”

4.删除(删除后在获取输出nil,表示删除不存在了)–del + “key”

5.自增1(将key对应的value自增1并将结果返回,如果key不存在则自动创建该key默认为0,自增1变为1,如果key对应的value不能转成整型将报错)–incr + “key”

6.自减1(同上)–decr + “key”

7.自加指定数值(同上)–incrby + “key” + 指定数值

8.自减指定数值(同上)–decrby + “key” + 指定数值

hash类型(String类型的key和value的容器,适合存放对对象)

1.单个赋值–hset + “hash名” + “key” + “value”

2.单个取值–hget + “hash名” + “key”

3.多个赋值–hmset + “hash名” + “key1” + “value1” + “key2” + “value2”……

4.多个取值–hmget + “hash名” + “key1” + “key2”……

5.获取该hash的所有属性–hgetall + “hash名”

6.删除某一属性–hdel + “hahs名” + “key”

7.删除该hash–del + “hash名”

8.对hash中某一属性自增/自减–hincrby/hdecrby + “hash名” + “key” + “指定数值”

9.判断该hash中是存在某个属性(存在返回1,不存在返回0)–hexists + “hash名” + “属性名”

10.返回该hash中属性的个数–hlen + “hash名”

11.返回该hash中所有属性名–hkeys + “hash名”

12.返回该hash中所有属性值–hvals + “hash名”

list类型

1.从左/右侧插入元素(开始list默认为空)–lpush/rpush + “list名” + “value1” + “value2”….

2.从左/右弹出元素–lpop/rpop + “list名”

3.查看list中元素(负数代表倒数第几个)–lrange + “list名” + “开始索引” + “结束索引”,比如0到-1表示查看整个list的元素

4.从头到尾删除m个指定元素n–lrem + “list名” + m + n(当m为0时,表示删除所有的n)

5.从尾到头删除m个指定元素n–lrem + “list名” + -m + n(当m为0时,表示删除所有的n)

6.修改下标为m的值为n(替换原m号元素)–lset + “list名” + m + n

7.在指定元素前/后插入元素–linsert + “list名” + before/after + “指定元素” + “待插入元素”

8.将list1的尾部元素移动到list2的头部–rpoplpush + “list1” + “list2”

set类型(无序,不重复)

1.添加元素–sadd + “list名” + “value1” + “value2”….

2.删除元素–srem + “list名” + “value1” + “value2” …..

3.求差(求出两个set中第一个不同的点)–sdiff + “set1” + “set2”

3.2将相差的元素存到另一个set3中–sdiffstore + “set3” + “set1” + “set2”

4.求交集–sinter + “set1” + “set2”

4.2将交集的元素存到另一个set3中–sinterstore + “set3” + “set1” + “set2”

5.求并集–sunion + “set1” + “set2”

5.2将并集的元素存到另一个set3中–sunionstore + “set3” + “set1” + “set2”

6.查看set中的元素–smembers + “set名”

7.获取set中元素的数量–scard + “set名”

8.随意获取set中的一个元素–srandmember + “set名”

sortedset类型(有序的不重复,元素唯一但分数可重复,默认从小到大排序)

1.添加元素–zadd + “sset名” + “分数1” + “元素1” + “分数2” + “元素2”…..

如果增加已存在的元素,那么该元素的分数将会是最新的分数

2.获取sset中某个元素的分数–zscore + “sset名” + “带查看分数的元素”

3.获取sset中元素的个数(分数和元素是一个整体)–zcard + “sset名”

4.删除元素–zrem + “sset名” + “元素名”

5.范围内查找/带分数–zrange + “sset名” + “开始索引” + “结束索引” /+ withscores

6.从大到小排序–zrevrange + “sset名” + 0 + -1(/也可以withscores)

7.删除指定排名范围的元素–zremrangebyrank + “sset名” + “开始排名(第一名是0)” + “末位排名”

8.删除指定分数范围内的元素–zremrangebyscore + “sset名” + “分数1” + “分数2”

9.返回指定分数范围内的元素–zrangebyscore + “sset名” + “分数1” + “分数2”;当然也可以带上withscores,也可以带上limit + “开始索引” + “结束索引”(限制返回其中的前几名)

10.给指定元素增加分数–zincrby + “sset名” + “增加的分数” + “元素名”

11.返回指定分数范围内元素的个数–zcount + “sset名” + “低分” + “高分”

三.redis的特性

1.多数据库

一个redis中可以包含多个数据库,就像mysql中可以创建多个数据库,用户进行链接时可以指定链接具体的某一个数据据库。一个redis实例最多提供16个数据库,下标分别为0到15。客户端默认连接的是0号数据库,当然也可以用select关键字来选择连接哪一个数据库:如选择1号数据库–select 1即可。将当前数据中的某个key移动到另一个数据库可以用move + “key” + “目标数据库序号”,如将当前数据库中的key1移动到0号数据中:move key1 0。

2.Redis事务

redis中也提供了事务的特性(multi、exec、discard),在redis中所有事务命令将会被放进队列中顺序串行化执行,并且在执行事务操作期间,redis将不会再为任何客户端提供服务,流程如下:

1.multi后面所有的语句都会被当作一个事务按序执行,相当于开启事务

2.exec相当于提交事务

3.discard相当于回滚事务

3.redis的持久化

redis的高性能源于他的所有数据都存放在内存中,为了数据不丢失,就需要将这些数据从内存中转存到本地硬盘上,这就是持久化,redis的持久化有两种方式:RDB方式和AOF方式。

1.RDB持久化:默认支持,不需要配置,在指定的时间间隔内将内存中数据集快照写入到磁盘。

优势:1.采用RDB持久化方式后,整个redis数据库将只包含一个文件,对于文件备份非常方便;2.对于灾难恢复而言,RDB是不错的选择,可以将单独的文件压缩后转移到其他介质上;3.性能最大化,在开始持久化时,redis需要做的仅仅是分叉出一些子进程去完成这些持久化的操作,极大的避免了服务器进程进行I/O操作。如果数据集很大,相对AOF,RDB的启动效率更高。

劣势:如果想保证数据的高可用性(最大限度避免数据丢失),那RDB不是一个很好的选择,因为RDB在定时持久化的时候不可避免的会出现宕机的情况,宕机前的数据就会丢失。RDB是利用子进程来协助完成持久化,所以当数据集非常大的时候,可能会导致整个服务器停止几百毫秒甚至1秒。

配置:在redis.conf文件中


这里的save 900 1表示每900秒至少有一个key发生变化时,redis就会持久化一次,即dump一次快照到磁盘上,下面的同理;dump的文件名


dump文件的路径,


即当前路径

2.AOF持久化:以日志的形式记录服务器的每一次操作,在redis启动时,就会读取该文件重新构建数据库,以保证数据库的完整。

优势:AOF可以带来更高的数据安全性,redis提供了三种同步策略:每秒同步(异步,高效,但一旦宕机,这1s秒修改的数据就会丢失)、每修改同步(同步持久化,最安全但效率最低)、不同步,对于日志的修改是append形式(追加的形式),即使出现宕机,也不会破坏之前以保存的日志,如果日志过大,redis可以启动自动重写机制。AOF有一个非常清晰的日志模式。

劣势:往往AOF的文件要比RDB文件大一些,而且运行效率比RDB低(因为每修改同步)

配置:同样在redis.conf文件中,

开启追加的模式将appendonly no改为yes,下面也标明了日志文件是appendonly.aof,同步策略如下


其中always表示是每修改同步(最常用),everysec则表示每秒同步,no表示不同步。使用AOF的案列:将appendonly no改为appendonly yes,使用appendsync always(每修改同步)策略,保存退出,然后在redis中随便写一些数据,最后执行flushall(清空数据库数据),再断开redis,然后进入日志文件appendonly.aof将最后的flushall命令删除重启redis,redis数据即可恢复

3.无持久化:直接禁用redis的持久化机制,就是用来做缓存

4.RDB和AOF结合

四.java对Redis的操作

下载jedis的jar包,Linux必须在配置开放对应的6379端口,redis的配置文件中要需要将绑定的ip改成0.0.0.0,不能为127.0.0.1,否则将会出现ping通,redis却链接超时的情况(redis后台启动必须带上配置文件,否则将是前台启动),代码如下

import org.junit.Test;

import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;

public class JedisDemo1 {

/*
* 单个链接的方式
*/
@Test
public void demo1() {
//设置IP地址和端口
Jedis jedis = new Jedis("10.4.62.6",6379);
//保存数据
jedis.set("name", "Hello Redis!");
//获取值
String value = jedis.get("name");
jedis.del("name");
System.out.println(value);
//释放资源
jedis.close();
}

/*
* 使用连接池链接
*/
@Test
public void demo2() {
//创建连接池的配置对象
JedisPoolConfig config = new JedisPoolConfig();
//设置最大连接数
config.setMaxTotal(30);
//设置最大空闲连接数
config.setMaxIdle(10);

//获得连接池
JedisPool jedisPool = new JedisPool(config, "10.4.62.6", 6379);

//获取和新对象
Jedis jedis = null;
try {
//通过连接池获得jedis
jedis = jedisPool.getResource();
jedis.set("jedisPool", "利用jedisPool设置的值");
System.out.println(jedis.get("jedisPool"));
} catch(Exception e) {
e.printStackTrace();
} finally {
if(jedis!=null) {
jedis.close();
}
if(jedisPool!=null) {
jedisPool.close();
}
}
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  redis