Redis是一个使用ANSI C编写的开源、支持网络、基于内存、可选持久性的键值对存储数据库 ——维基百科java
能够简单的说,Redis就是一款高性能的NoSQL数据库linux
咱们前面所学习的MySQL数据库是典型的的SQL数据库也就是传统的关系型数据库,而咱们今天学习的Redis数据库则是一款NoSQL数据库,也叫做非关系型数据库,它与咱们熟悉的MySQL等的概念彻底是不同的,它是一项全新的数据库理念,咱们帖一组百度百科的解释git
NoSQL,泛指非关系型的数据库。随着互联网web2.0网站的兴起,传统的关系数据库在处理web2.0网站,特别是超大规模和高并发的SNS类型的web2.0纯动态网站已经显得力不从心,出现了不少难以克服的问题,而非关系型的数据库则因为其自己的特色获得了很是迅速的发展。NoSQL数据库的产生就是为了解决大规模数据集合多重数据种类带来的挑战,尤为是大数据应用难题 ——百度百科github
说明:咱们如今所看到的的博客,RSS,P2P,微博,抖音等均属于 Web2.0的产物,Web2.0相比较过去的Web1.0更加注重于用户的交互,用户不只能够浏览,还能够上传一些资源到网站上,例如图片文字或者说短视频等,使得用户也参与到了网站内容的制造中去了web
有人会说,NoSQL = Not SQL ,可是我更倾向这样理解 NoSQL = Not only SQL ,咱们不能以一个绝对的结论来断定两项技术的好坏,每一项技术的产生都有其特定的缘由,在我看来,NoSQL更适合做为SQL数据库的补充,因为海量数据的出现,性能的要求高了起来,而NoSQL这种产物,对于结构简单可是数据量大的数据处理起来要比传统的SQL快不少,可是一样的,其逻辑运算就必须很简单,不然它也是力不从心的redis
在我看来,能够简单的说,NoSQL就是以功能换取性能,可是须要处理复杂的业务逻辑还须要使用关系型数据库,因此说想要在模型中彻底用NoSQL替代SQL是不现实的,二者更像是互补的关系数据库
SQL的好处:windows
市面上的NoSQL产品很是多,咱们今天所要介绍的就是其中一款基于键值存储的数据库——Redis缓存
咱们在一开始提到了,Redis就是一款高性能的NoSQL数据库,那么它的应用场景是什么呢?安全
用于用户内容缓存,能够处理大量数据的高访问负载,例如:数据查询,新闻,商品内容
任务队列,例如:秒杀,12306
在线好友列表
应用、网站访问统计排行
因为其基于键值存储,那么能够支持的存储的类型有什么呢?
字符串类型 - String
列表 - list:linkedlist
集合 - set
有序集合 - sortedset
哈希 - hash:map
官网:redis.io
因为官网访问速度过慢,咱们能够访问对应的中文网:www.redis.net.cn
下载,解压,编译:
$ wget http://download.redis.io/releases/redis-5.0.4.tar.gz
$ tar xzf redis-5.0.4.tar.gz
$ cd redis-5.0.4
$ make
复制代码
二进制文件是编译完成后在src目录下. 运行以下:
$ src/redis-server
复制代码
你能使用Redis的内置客户端进行进行redis代码的编写,例如咱们存入一个键值 name-zhangsan
$ src/redis-cli
redis> set name zhangsan
OK
redis> get name
"zhangsan"
复制代码
咱们能够去github中寻找windows版本,不过版本会有所滞后
解压便可用
redis-server.exe:redis服务器端
redis-cli.exe:redis的客户端
redis.windows.conf:配置文件
- 127.0.0.1:6379> set address beijing
- OK
复制代码
- 127.0.0.1:6379> get address
- “beijing”
复制代码
- 127.0.0.1:6379> del address
- (integer) 1
复制代码
添加一个元素到列表的头部(左边)或者尾部(右边)
127.0.0.1:6379> lpush listDemo zhangsan
(integer) 1
127.0.0.1:6379> lpush listDemo lisi
(integer) 2
127.0.0.1:6379> rpush listDemo wangwu
(integer) 3
复制代码
1) "lisi"
2) "zhangsan"
3) "wangwu"
复制代码
set:String 类型的无序集合,且元素不能重复
127.0.0.1:6379> sadd setDemo aaa
(integer) 1
127.0.0.1:6379> sadd setDemo aaa
(integer) 0
复制代码
127.0.0.1:6379> smembers setDemo
1) "aaa“ 复制代码
127.0.0.1:6379> srem setDemo aaa
(integer) 1
复制代码
sortedset 和 set 同样也是 string 类型元素的集合,且不容许重复的元素
不一样的是每一个元素都会关联一个double类型的分数,redis正是经过分数来为集合中的成员进行从小到大的排序
有序集合的成员是惟一,但分数(score)却能够重复
127.0.0.1:6379> zadd sortedsetDemo 20 zhangsan
(integer) 1
127.0.0.1:6379> zadd sortedsetDemo 10 lisi
(integer) 1
127.0.0.1:6379> zadd sortedsetDemo 60 wangwu
(integer) 1
复制代码
127.0.0.1:6379> zrange sortedsetDemo 0 -1
1) "lisi"
2) "zhangsan"
3) "wangwu"
复制代码
127.0.0.1:6379> zrem sortedsetDemo wangwu
(integer) 1
复制代码
127.0.0.1:6379> hset hashDemo username admin
(integer) 1
127.0.0.1:6379> hset hashDemo password admin
(integer) 1
复制代码
127.0.0.1:6379> hget hashDemo password
"admin"
复制代码
127.0.0.1:6379> hgetall hashDemo
1) "username"
2) "admin"
3) "password"
4) "admin"
复制代码
127.0.0.1:6379> hdel hashDemo username
(integer) 1
复制代码
开篇已经讲过,Redis是一个内存数据库,也就是说,咱们的数据所有存储在内存中,而咱们常见的MySQL和Oracle等SQL数据库会将数据存储到硬盘中,凡事都是有利有弊,虽然内存数据库读写速度要比在硬盘中读写的数据库快的多,可是却出现了一个很麻烦的问题,也就是说,当 Redis 服务器重启或者宕机后,内存中的数据会所有丢失,为了解决这个问题,Redis提供了一种持久化的技术,也就是将内存中的数据存储到硬盘中去,往后方便咱们使用这些文件恢复数据库中的数据
RDB:必定的时间内,检测key的变化状况,而后持久化数据
咱们想要配置它,须要编辑 redis.windows.conf 配置文件
# Save the DB on disk:
#
# save <seconds> <changes>
#
# Will save the DB if both the given number of seconds and the given
# number of write operations against the DB occurred.
#
# In the example below the behaviour will be to save:
# after 900 sec (15 min) if at least 1 key changed
# after 300 sec (5 min) if at least 10 keys changed
# after 60 sec if at least 10000 keys changed
# ......省略部分
save 900 1
save 300 10
save 60 10000
复制代码
咱们须要修改的就是最后三行,前面的说明的意思是,若是给定的秒数和给定的对数据库的写操做数同时发生,那么将保存数据库,也就是说,它的配置是根据save后面的两个数字,根听说明可知,第一个数字表明间隔时间,第二个数表明操做数据的数量
例如第一个 save 900 1 ,就是说每900秒且,至少一个 key 被改变则保存数据
咱们根据本身具体项目的须要设置好后,须要从新启动Redis的服务器,而且咱们须要指定配置文件,咱们先指向到Redis指定目录下, 而后输入命令 redis-server.exe redis.windows.conf
例如我本地:D:\Tools\Redis-x64-3.2.100>redis-server.exe redis.windows.conf
AOF:每一次操做后,就持久化数据
咱们一样能够在 redis.windows.conf 文件配置
咱们找到这一行
appendonly no
no表明关闭aof,改成yes表明开启
还有这一行
# appendfsync no
:不进行持久化
咱们能够修改 no 位置的值
Jedis is a blazingly small and sane Redis java client.
Jedis was conceived to be EASY to use.
Jedis 是一款可让咱们在java中操做redis数据库的工具,下载其jar包导入便可,使用仍是很是简单的
//获取链接,空构造表明默认值 "localhost",6379端口
Jedis jedis = new Jedis();
//存储
jedis.set("address","beijing");
//获取
String address = jedis.get("address");
//关闭链接
jedis.close();
复制代码
补充:setex() 方法能够存储数据,而且指定过时时间
//将aaa-bbb存入,且10秒后过时
jedis.setex("aaa",10,"bbb")
复制代码
//获取链接,空构造表明默认值 "localhost",6379端口
Jedis jedis = new Jedis();
//存储
jedis.lpush("listDemo","zhangsan","lisi","wangwu");//从左
jedis.rpush("listDemo","zhangsan","lisi","wangwu");//从右
//获取
List<String> mylist = jedis.lrange("listDemo", 0, -1);
//删除,而且返回元素
String e1 = jedis.lpop("listDemo");//从左
String e2 = jedis.rpop("listDemo");//从右
//关闭链接
jedis.close();
复制代码
//获取链接,空构造表明默认值 "localhost",6379端口
Jedis jedis = new Jedis();
//存储
jedis.sadd("setDemo","zhangsan","lisi","wangwu");
//获取
Set<String> setDemo = jedis.smembers("setDemo");
//关闭链接
jedis.close();
复制代码
//获取链接,空构造表明默认值 "localhost",6379端口
Jedis jedis = new Jedis();
//存储
jedis.zadd("sortedsetDemo",20,"zhangsan");
jedis.zadd("sortedsetDemo",10,"lisi");
jedis.zadd("sortedsetDemo",60,"wangwu");
//获取
Set<String> sortedsetDemo = jedis.zrange("sortedsetDemo", 0, -1);
//关闭链接
jedis.close();
复制代码
//获取链接,空构造表明默认值 "localhost",6379端口
Jedis jedis = new Jedis();
//存储
jedis.hset("hashDemo","name","lisi");
jedis.hset("hashDemor","age","20");
//获取
String name = jedis.hget("hashDemo", "name");
//获取全部数据
Map<String, String> user = jedis.hgetAll("hashDemo");
Set<String> keySet = user.keySet();
for (String key : keySet) {
//获取value
String value = user.get(key);
System.out.println(key + ":" + value);
}
//关闭链接
jedis.close();
复制代码
为何咱们要使用链接池呢?
咱们要使用Jedis,必须创建链接,咱们每一次进行数据交互的时候,都须要创建链接,Jedis虽然具备较高的性能,但创建链接却须要花费较多的时间,若是使用链接池则能够同时在客户端创建多个链接而且不释放,链接的时候只须要经过必定的方式获取已经创建的链接,用完则归还到链接池,这样时间就大大的节省了
//建立一个配置对象
JedisPoolConfig config = new JedisPoolConfig();
config.setMaxIdle(10);
//建立Jedis链接池对象
JedisPool jedisPool = new JedisPool(config,"localhost",6379);
//获取链接
Jedis jedis = jedisPool.getResource();
//使用
jedis.set("setDemo","zhangsan");
//关闭 归还到链接池中
jedis.close();
复制代码
public class JedisPoolUtils {
private static JedisPool jedisPool;
//静态代码初始化池配置
static{
//建立Properties对象
Properties pro = new Properties();
//读取配置文件
InputStream is = JedisPoolUtils.class.getClassLoader().getResourceAsStream("jedis.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();
}
}
复制代码
若是文章中有什么不足,或者错误的地方,欢迎你们留言分享想法,感谢朋友们的支持!
若是能帮到你的话,那就来关注我吧!若是您更喜欢微信文章的阅读方式,能够关注个人公众号
在这里的咱们素不相识,却都在为了本身的梦而努力 ❤
一个坚持推送原创开发技术文章的公众号:理想二旬不止