NoSQL(Not Only SQL),意即“不仅仅是SQL”,是一项全新的数据库理念,泛指非关系型的数据库。
传统的关系数据库在应付web2.0网站,特别是超大规模和高并发的SNS类型的web2.0纯动态网站已经显得力不从心,暴露了很多难以克服的问题,如:
NoSQL数据库的诞生就是为了解决大规模数据集合和多重数据种类带来的挑战,尤其是大数据应用难题。
相关产品: Tokyo Cabinet/Tyrant、Redis、Voldemort、Berkeley DB
典型应用: 内容缓存,主要用于处理大量数据的高访问负载
数据模型: 一系列键值对
优势: 快速查询
劣势: 存储的数据缺少结构化
相关产品:Cassandra、HBase、Riak
典型应用:分布式的文件系统
数据模型:以列簇式存储,将同一列数据存在一起
优势:查找速度快,可扩展性强,更容易进行分布式扩展
劣势:功能相对局限
相关产品:CouchDB、MongoDB
典型应用:Web应用(与Key-Value类似,Value是结构化的)
数据模型: 一系列键值对
优势:数据结构要求不严格
劣势: 查询性能不高,而且缺乏统一的查询语法
相关数据库:Neo4J、InfoGrid、Infinite Graph
典型应用:社交网络
数据模型:图结构
优势:利用图结构相关算法。
劣势:需要对整个图做计算才能得出结果,不容易做分布式的集群方案
2008年,意大利的一家创业公司Merzia推出了一款基于MySQL的网站实时统计系统LLOOGG,然而没过多久该公司的创始人 Salvatore Sanfilippo便 对MySQL的性能感到失望,于是他决定亲自为LLOOGG量身定做一个数据库,并于2009年开发完成,这个数据库就是Redis。 不过Salvatore Sanfilippo并不满足只将Redis用于LLOOGG这一款产品,而是希望更多的人使用它,于是在同一年Salvatore Sanfilippo将Redis开源发布,并开始和Redis的另一名主要的代码贡献者Pieter Noordhuis一起继续着Redis的开发,直到今天。
Salvatore Sanfilippo自己也没有想到,短短的几年时间,Redis就拥有了庞大的用户群体。Hacker News在2012年发布了一份数据库的使用情况调查,结果显示有近12%的公司在使用Redis。国内如新浪微博、街旁网、知乎网,国外如GitHub、Stack Overflow、Flickr等都是Redis的用户。
VMware公司从2010年开始赞助Redis的开发, Salvatore Sanfilippo和Pieter Noordhuis也分别在3月和5月加入VMware,全职开发Redis。
Redis是用C语言开发的一个开源的高性能键值对(key-value)数据库。它通过提供多种键值数据类型来适应不同场景下的存储需求,目前为止Redis支持的键值数据类型如下:
字符串类型 string
散列类型 hash
列表类型 list
集合类型 set
有序集合类型 sorted set
官方提供测试数据:50个并发执行100000个请求,读的速度是110000次/s,写的速度是81000次/s(数据仅供参考,根据服务器配置会有不同结果)。
缓存(数据查询、短连接、新闻内容、商品内容等等)
聊天室的在线好友列表
任务队列(秒杀、抢购、12306等等)
应用排行榜
网站访问统计
数据过期处理(可以精确到毫秒)
分布式集群架构中的session分离
dbsize
查看key的个数flushdb
清空当前数据flushall
清空所有数据库,16个库全删(删的是数据)del key
根据key删除keys *
查看所有keytype key
查询key的类型,根据类型 就可以使用不同的apittl key
查看key的有效时间 1 永不超时; -2 没有这个数据或者这个数据已经过时了;正数: 还有多少秒过期expire key s
设置数据的过期时间 单位秒 例如:expire name 20 表示key为name的缓存20秒后过期hset key filed value
存入一个字段,一个值hmset key field value field value
存入多个字段多个值hget key filed
取出对应key的值hdel key flied
删除keyhgetall key
查询所有keykey:{fieldname:fieldvalue,fieldname:fieldvalue}
user: {username:zhangsan,gender:male,age:18}
lpush key value value value
左添加rpush key value value value
右添加lrange key startIndex endIndex
获取,startIndex为0时,表示从左开始开始查询;-1表示从右开始lpop key
左移除,从左弹出数据rpop key
右移除,从右弹出数据 key:[91,93,95]
sadd key value value value
存入smembers key
获取srem key value value
移除和list基本一致,唯一区别就是不能重复
zadd key socre value socre value socre value
存入zscore key member
获得指定成员的分数zrange key start end [withscores]
升序查询数据zrevrange key start end [withscores]
降序查询数据zrem key member
删除指定的成员在set的基础上进行了一定的增强,有序不重复
导入依赖
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>3.2.0</version>
</dependency>
demo
import redis.clients.jedis.Jedis;
public class JedisTest {
public static void main(String[] args) {
//1.创建jedis对象
Jedis jedis = new Jedis("localhost",6379);
//2.调用api,存入redis
jedis.set("username","张三");
//3.调用api从redis获取
String username = jedis.get("username");
//4.输出
System.out.println(username);
//5.释放资源
jedis.close();
}
}
JedisPool Demo
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;
public class JedisPoolTest {
public static void main(String[] args) {
//1.创建jedis配置对象
JedisPoolConfig config = new JedisPoolConfig();
//2.设置参数
config.setMinIdle(3);//最小空闲数
config.setMaxWaitMillis(3000); //最大等待时间
config.setMaxTotal(30);//最大连接数
//3.创建jedis连接池
JedisPool jedisPool = new JedisPool(config,"localhost",6379);
//4.获取连接
Jedis jedis = jedisPool.getResource();
//5.执行操作
System.out.println(jedis.keys("*"));
//6.释放
jedis.close();
jedisPool.close();
}
}
抽取工具类
jedis.maxTotal=30
jedis.minIdle=3
jedis.maxWaitMillis=3000
jedis.host=127.0.0.1
jedis.port=6379
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;
import java.util.Properties;
import java.util.ResourceBundle;
/**
* 工具类
* 目标提供jedis连接对象
*/
public class JedisUtils {
//定义池对象
private static JedisPool pool = null;
private static ResourceBundle bundle = null;
static{
/**
* ResourceBundle 专门用来操作properties
* ResourceBundle.getBundle("jedis"); 获得配置文件 (此处不需要后缀)
*/
//读取配置文件
bundle = ResourceBundle.getBundle("jedis");
int minIdle= Integer.valueOf( bundle.getString("jedis.minIdle") );
int maxWaitMillis = Integer.valueOf( bundle.getString("jedis.maxWaitMillis") );
int maxTotal = Integer.valueOf( bundle.getString("jedis.maxTotal") );
int port = Integer.valueOf( bundle.getString("jedis.port") );
String host = bundle.getString("jedis.host");
//创建配置
JedisPoolConfig config = new JedisPoolConfig();
//创建池
pool = new JedisPool( config,host ,port );
}
/**
* 提供jedis连接对象
* @return
*/
public static Jedis getJedis(){
return pool.getResource();
}
public static void main(String[] args) {
Jedis jedis = JedisUtils.getJedis();
System.out.println(jedis);
}
}
该机制是指在指定的时间间隔内将内存中的数据集快照写入磁盘。
RDB优势:
RDB劣势:
如果想保证数据的高可用性,即最大限度的避免数据丢失,那么RDB将不是一个很好的选择。因为系统一旦在定时持久化之前出现宕机现象,此前没有来得及写入磁盘的数据都将丢失
由于RDB是通过fork子进程来协助完成数据持久化工作的,因此,如果当数据集较大时,可能会导致整个服务器停止服务几百毫秒,甚至是1秒钟
save 900 1 #每900秒(15分钟)至少有1个key发生变化,则dump内存快照。
save 300 10 #每300秒(5分钟)至少有10个key发生变化,则dump内存快照
save 60 10000 #每60秒(1分钟)至少有10000个key发生变化,则dump内存快照
该机制将以日志的形式记录服务器所处理的每一个写操作,在Redis服务器启动之初会读取该文件来重新构建数据库,以保证启动后数据库中的数据是完整的。
AOF优势:
AOF劣势:
重写AOF:若不满足重写条件时,可以手动重写,命令:bgrewriteaof
注意:
redis如果希望启动日志机制,需要以配置文件方式启动redis
数据恢复演示:
flushall操作 清空数据库
及时关闭redis服务器(防止dump.rdb)。 shutdown nosave
编辑aof文件,将日志中的flushall命令删除并重启服务即可