Redis笔记

redis是一款高性能的NOSQL系列的非惯性数据库
什么是NOSQL
NoSQL(NoSQL = Not Only SQL),意即“不仅仅是SQL”,是一项全新的数据库理念,泛指非关系型的数据库。
随着互联网web2.0网站的兴起,传统的关系数据库在应付web2.0网站,特别是超大规模和高并发的SNS类型的web2.0纯动态网站已经显得力不从心,暴露了很多难以克服的问题,而非关系型的数据库则由于其本身的特点得到了非常迅速的发展。NoSQL数据库的产生就是为了解决大规模数据集合多重数据种类带来的挑战,尤其是大数据应用难题。

NOSQ非关系型数据库
没有表的概念
存储在内存中 效率非常高

一般使用非关系数据库做缓存使用

能缓存的尽量缓存
前台 后台 数据库服务器
前台发送请求到后台 后台发送请求去数据库查询数据
前台可以缓存一些经常请求的数据 减少到后台服务器的请求次数 相对应的就是减轻后台服务器的压力
后台可以缓存前台经常查询的内容 减少后台到数据库服务器的请求次数 相对应的就是减轻数据库服务器的压力
能延迟的就尽量延迟
创建对象的时候 什么时候使用什么时候加载
非关系型数据库一般不支持事务操作 不支持存储过程…

NOSQL和关系型数据库比较
优点:

  1. 成本:nosql数据库简单易部署,基本都是开源软件,不需要像使用oracle那样花费大量成本购买使用,相比关系型数据库价格便宜。
  2. 查询速度:nosql数据库将数据存储于缓存之中,关系型数据库将数据存储在硬盘中,自然查询速度远不及nosql数据库。
  3. 存储数据的格式:nosql的存储格式是key,value形式、文档形式、图片形式等等,所以可以存储基础类型以及对象或者是集合等各种格式,而数据库则只支持基础类型。
  4. 扩展性:关系型数据库有类似join这样的多表查询机制的限制导致扩展很艰难。

缺点:

  1. 维护的工具和资料有限,因为nosql是属于新的技术,不能和关系型数据库10几年的技术同日而语。
  2. 不提供对sql的支持,如果不支持sql这样的工业标准,将产生一定用户的学习和使用成本。
  3. 不提供关系型数据库对事务的处理。

非关系型数据库的优势:

  1. NOSQL基于键值对,可以想象成表中的键和值的对应关系,而且不需要经过SQL层的解析,所以性能非常高
  2. 可扩展性同样也是因为基于键值对,数据之间没有耦合性,非常容易水平扩展

关系型数据库的优势:

  1. 复杂查询可以用SQL语句方便的在一个表以及多个表之间做非常复杂的数据查询
  2. 事务支持使得对于安全性能很高的数据访问要求得以实现,关系型数据库和非关系型数据库可以互补

关系型数据库与NoSQL数据库并非对立而是互补的关系,即通常情况下使用关系型数据库,在适合使用NoSQL的时候使用NoSQL数据库,
让NoSQL数据库对关系型数据库的不足进行弥补。
一般会将数据存储在关系型数据库中,在nosql数据库中备份存储关系型数据库的数据

主流NOSQL产品
键值(Key-Value)存储数据库
相关产品: Tokyo Cabinet/Tyrant、Redis、Voldemort、Berkeley DB
典型应用: 内容缓存,主要用于处理大量数据的高访问负载。
数据模型: 一系列键值对
优势: 快速查询
劣势: 存储的数据缺少结构化

列存储数据库
相关产品:Cassandra, HBase, Riak
典型应用:分布式的文件系统
数据模型:以列簇式存储,将同一列数据存在一起
优势:查找速度快,可扩展性强,更容易进行分布式扩展
劣势:功能相对局限
文档型数据库
相关产品:CouchDB、MongoDB
典型应用:Web应用(与Key-Value类似,Value是结构化的)
数据模型: 一系列键值对
优势:数据结构要求不严格
劣势: 查询性能不高,而且缺乏统一的查询语法

图形(Graph)数据库
相关数据库:Neo4J、InfoGrid、Infinite Graph
典型应用:社交网络
数据模型:图结构
优势:利用图结构相关算法。
劣势:需要对整个图做计算才能得出结果,不容易做分布式的集群方案。

REDIS

Redis是用C语言开发的一个开源的高性能键值对(key-value)数据库,官方提供测试数据,50个并发执行100000个请求,读的速度是110000次/s,写的速度是81000次/s ,且Redis通过提供多种键值数据类型来适应不同场景下的存储需求
目前为止Redis支持的键值数据类型如下:
字符串类型 String
哈希类型 hash
列表类型 list
集合类型 set
有序集合类型 sortedset

redis的应用场景
缓存:数据查询,短链接,新闻内容,商品内容
聊天室的在线好友列表
任务队列:秒杀,抢购,12306
应用排行榜
网站访问统计
数据过期处理:可以精确到毫秒
分布式集群架构中的session分离

redis的数据结构
redis存储的是:key,value格式的数据,其中key都是字符串,value有5种不同的数据结构
key:value
value:
字符串类型:string
哈希类型hash:map格式
列表类型list:linkedlist格式,支付重复元素
集合类型set:不允许重复元素
有序集合类型sortedset:不允许重复元素,且元素有顺序

字符串类型string
1.存储: set key value
2.获取:get key
3.删除:del key

在redis中存值的时候key的长度尽量不要超过1024字节
也不能太短,可读性太差

哈希类型hash
1.存储:hset key field value
2.获取:
hget key field
hgetall key:获得所有的key和value
3.删除:hdel key field

列表类型 list
1.添加:
lpush key value:将元素加入列表左边
rpush key value
2.获取
lrange key start end:范围获取
3.删除
lpop key:删除列表最左边的元素
rpop key
lrem key count field :count正数则是从左边开始查询该数量对应键的元素删除

集合类型 set
不允许重复元素
1.存储:sadd key value
2.获取:smembers key:获取set集合中所有元素
3.删除:srem key value:删除set集合中的某个元素

有序集合类型 sortedset
不允许重读元素,且元素有顺序,每个元素都会关联一个double类型的分数,从小到大进行排序

1.存储:zadd key score value
2.获取:zrange key start end [withscores]
3.删除:zrem key value

通用命令
1.keys *:查询所有的键
2.type key:获取键对应的value类型
3.del key:删除指定的key value

持久化

为什么要持久化 因为redis是把数据保存到内存中的 如果关机或者关闭redis服务器 数据就丢失了
RDB 保存的是某一个时刻的数据的快照 有可能会造成数据丢失
AOF 是记录你的操作命令 备份的是执行命令 不可能造成数据丢失
redis官方推荐的是 RDB + AOF

redis的持久化机制
RDB:默认方式
在一定的时间间隔中,检测key的变化情况,然后持久化数据
1.编辑redis.windows.conf文件

after 900 sec (15 min) if at least 1 key changed

2.cmd重新启动redis服务器,并指定配置文件名称

AOF:日志记录的方式,可以记录每一条命令的操作,可以每一次命令操作后持久化数据
1.编辑redis.windows.conf文件

appendonly no(关闭aof) --> appendonly yes (开启aof)
appendfsync always : 每一次操作都进行持久化
appendfsync everysec : 每隔一秒进行一次持久化
appendfsync no : 不进行持久化

RDB简而言之,就是在不同的时间点,将redis存储的数据生成快照并存储到磁盘等建置上
RDB方式,是将redis某一时刻的数据持久化到磁盘中,是一种快照式的持久化方法。
对于RDB方式,redis会单独创建(fork)一个子进程来进行持久化,而主进程是不会进行任何IO操作的,这样就确保了redis极高的性能。
虽然RDB有不少优点,但它的缺点也是不容忽视的。如果你对数据的完整性非常敏感,那么RDB方式就不太适合你,因为即使你每5分钟都持久化一次,当redis故障时,仍然会有近5分钟的数据丢失。所以,redis还提供了另一种持久化方式,那就是AOF。

AOF,则是换了一个角度来实现持久化,那就是将redis执行过的所有写指令记录下来,在下次redis重新启动时,只要把这些写指令从前到后再重复执行一遍,就可以实现数据恢复了。
AOF,英文是Append Only File,即只允许追加不允许改写的文件。
如前面介绍的,AOF方式是将执行过的写指令记录下来,在数据恢复时按照从前到后的顺序再将指令都执行一遍,就这么简单。
默认的AOF持久化策略是每秒钟fsync一次(fsync是指把缓存中的写指令记录到磁盘中),因为在这种情况下,redis仍然可以保持很好的处理性能,即使redis故障,也只会丢失最近1秒钟的数据。

其实RDB和AOF两种方式也可以同时使用,在这种情况下,如果redis重启的话,则会优先采用AOF方式来进行数据恢复,这是因为AOF方式的数据恢复完整度更高。

如果你没有数据持久化的需求,也完全可以关闭RDB和AOF方式,这样的话,redis将变成一个纯内存数据库,就像memcache一样。

Java客户端Jedis

Jedis:一款java操作redis数据库的工具
使用步骤:
1. 下载jedis的jar包
2. 使用 redis版本和jedis版本不对应
//1. 获取连接
Jedis jedis = new Jedis(“localhost”,6379);
//2. 操作
jedis.set(“username”,“zhangsan”);
//3. 关闭连接
jedis.close();

Jedis操作各种redis中的数据结构

  1. 字符串类型 string
    set
    get
	//1. 获取连接
Jedis jedis = new Jedis();//如果使用空参构造,默认值 "localhost",6379端口
//2. 操作
//存储
jedis.set("username","zhangsan");
//获取
String username = jedis.get("username");
System.out.println(username);
//可以使用setex()方法存储可以指定过期时间的 key value
jedis.setex("activecode",20,"hehe");//将activecode:hehe键值对存入redis,并且20秒后自动删除该键值对
//3. 关闭连接
jedis.close();
  1. 哈希类型 hash : map格式
    hset
    hget
    hgetAll
	//1. 获取连接
	Jedis jedis = new Jedis();//如果使用空参构造,默认值 "localhost",6379端口
	//2. 操作
	// 存储hash
	jedis.hset("user","name","lisi");
	jedis.hset("user","age","23");
	jedis.hset("user","gender","female");

	// 获取hash
	String name = jedis.hget("user", "name");
	System.out.println(name);


	// 获取hash的所有map中的数据
	Map<String, String> user = jedis.hgetAll("user");

	// keyset
	Set<String> keySet = user.keySet();
	for (String key : keySet) {
		//获取value
		String value = user.get(key);
		System.out.println(key + ":" + value);
	}

	//3. 关闭连接
	jedis.close();
  1. 列表类型 list : linkedlist格式。支持重复元素
    lpush / rpush
    lpop / rpop
    lrange start end : 范围获取
		//1. 获取连接
	Jedis jedis = new Jedis();//如果使用空参构造,默认值 "localhost",6379端口
	//2. 操作
	// list 存储
	jedis.lpush("mylist","a","b","c");//从左边存
	jedis.rpush("mylist","a","b","c");//从右边存

	// list 范围获取
	List<String> mylist = jedis.lrange("mylist", 0, -1);
	System.out.println(mylist);
	
	// list 弹出
	String element1 = jedis.lpop("mylist");//c
	System.out.println(element1);

	String element2 = jedis.rpop("mylist");//c
	System.out.println(element2);

	// list 范围获取
	List<String> mylist2 = jedis.lrange("mylist", 0, -1);
	System.out.println(mylist2);

	//3. 关闭连接
	jedis.close();

  1. 集合类型 set : 不允许重复元素
    sadd
    smembers:获取所有元素
	//1. 获取连接
	Jedis jedis = new Jedis();//如果使用空参构造,默认值 "localhost",6379端口
	//2. 操作

	// set 存储
	jedis.sadd("myset","java","php","c++");

	// set 获取
	Set<String> myset = jedis.smembers("myset");
	System.out.println(myset);

	//3. 关闭连接
	jedis.close();

5) 有序集合类型 sortedset:不允许重复元素,且元素有顺序
	zadd
	zrange

	//1. 获取连接
	Jedis jedis = new Jedis();//如果使用空参构造,默认值 "localhost",6379端口
	//2. 操作
	// sortedset 存储
	jedis.zadd("mysortedset",3,"亚瑟");
	jedis.zadd("mysortedset",30,"后裔");
	jedis.zadd("mysortedset",55,"孙悟空");

	// sortedset 获取
	Set<String> mysortedset = jedis.zrange("mysortedset", 0, -1);
	System.out.println(mysortedset);

	//3. 关闭连接
	jedis.close();
  • jedis连接池: JedisPool

  • 使用:

    1. 创建JedisPool连接池对象
    2. 调用方法 getResource()方法获取Jedis连接
		//0.创建一个配置对象
		JedisPoolConfig config = new JedisPoolConfig();
		config.setMaxTotal(50);
		config.setMaxIdle(10);

		//1.创建Jedis连接池对象
		JedisPool jedisPool = new JedisPool(config,"localhost",6379);

		//2.获取连接
		Jedis jedis = jedisPool.getResource();
		//3. 使用
		jedis.set("hehe","heihei");

		//4. 关闭 归还到连接池中
		jedis.close();
  • 连接池工具类
    public class JedisPoolUtils {
    	private static JedisPool jedisPool;
    	static{
    		//读取配置文件
    		InputStream is = JedisPoolUtils.class.getClassLoader().getResourceAsStream("jedis.properties");
    		//创建Properties对象
    		Properties pro = new Properties();
    		//关联文件
    		try {
    			pro.load(is);
    		} catch (IOException e) {
    			e.printStackTrace();
    		}
    		//获取数据,设置到JedisPoolConfig中
    		JedisPoolConfig config = new JedisPoolConfig();
    		config.setMaxTotal(Integer.parseInt(pro.getProperty("maxTotal")));
    		config.setMaxIdle(Integer.parseInt(pro.getProperty("maxIdle")));
    		//初始化JedisPool
    		jedisPool = new JedisPool(config,pro.getProperty("host"),Integer.parseInt(pro.getProperty("port")));
    	}
    	/**
    		* 获取连接方法
    		*/
    	public static Jedis getJedis(){
    		return jedisPool.getResource();
    	}
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值