本人小白一枚,欢迎大家一起讨论学习,如有错误,还望大家指教。
简述:
redis是一款高性能NOSQL系列的数据库。和Memcached类似,它支持存储的value类型相对更多,包括string(字符串)、list(链表)、set(集合)、zset(sorted set有序集合)和hash(哈希类型。这些数据类型都支持push/pop、add/remove及取交集并集和差集及更丰富的操作,而且这些操作都是原子性的。
在此基础上,redis支持各种不同方式的排序。与Memcached一样,为了保证效率,数据都是缓存在内存中。区别的是redis会周期性的把更新的数据写入磁盘或者把修改操作写入追加的记录文件,并且在此基础上实现了master-slave(主从)同步。
redis是一个高性能的key-value数据库。 redis的出现,很大程度补偿了memcached这类key/value存储的不足,在部分场合可以对关系数据库起到很好的补充作用。它提供了Java,C/C++,C#,PHP,JavaScript,Perl,Object-C,Python,Ruby,Erlang等客户端,使用很方便。
redis支持主从同步。数据可以从主服务器向任意数量的从服务器上同步,从服务器可以是关联其他从服务器的主服务器。这使得Redis可执行单层树复制。存盘可以有意无意的对数据进行写操作。由于完全实现了发布/订阅机制,使得从数据库在任何地方同步树时,可订阅一个频道并接收主服务器完整的消息发布记录。同步对读取操作的可扩展性和数据冗余很有帮助。
什么是NOSQL?
NOSQL全称为Not Only SQL
,译为“不仅仅是SQL”
,是一个全新的数据库理念,泛指非关系型
的数据库。随着互联网web2.0网站的兴起,传统的关系数据库在应对web2.0网站,特别是超大规模和高并发的SNS类型的web2.0纯动态网站已经显得力不从心,暴露了很多难以克服的问题,而非关系型的数据库则由于其本身的特点的得到了非常迅速的发展。NoSQL数据库的产生就是为了解决大规模数据集合多重数据种类带来的挑战,尤其是大数据应用难题。
对比非关系型和关系型数据库的优缺点?
优点:
- 成本:nosql数据库简单易部署,基本都是开源软件,不需要像使用oracle那样花费大量成本购买使用,相对于关系型数据库价格便宜。
- 查询速度:nosql数据库将数据存储于缓存之中,关系型数据库将数据存储在硬盘之中,自然而然,关系型数据库的查询速度远不及nosql数据库。
- 存储数据的格式:NOSQL的存储格式是key,value形式、文档形式、图片形式等,所以可以存储基础类型以及对象或者集合等各种格式,而数据库则只支持基础类型。
- 扩展性:关系型数据库有类似jion这样多表查询的机制导致扩展起来很困难。
缺点:
- 维护的工具和资料有限,因为nosql属于新的技术,无法和关系型数据库十几年技术进行相比。
- 不提供对SQL的支持,因为不支持SQL这样的工业标准,将产生一定用户的学习和使用成本。
- 不提供关系型数据库对事物的处理。
非关系型和关系型数据库的优势:
非关系型数据库的优势:
- NOSQL的存储是基于键值对的,并且不需要经过SQL层的解析,所以性能好。
- 因其基于键值对形式存储,所以数据之间没有耦合性,非常利于水平扩展,可扩展性好。
关系型数据库的优势:
- 可以用SQL语句对在一个表以及多个表之间做非常复杂的数据查询。
- 支持事物使得关系型数据库的数据安全性很高。
总结:
关系型数据库与非关系型数据库的关系并非对立,而是互补的关系。即通常情况下使用关系型数据库,在适合使用非关系型使用非关系型数据库,让非关系型数据库对关系型数据库的不足进行弥补。一般会将数据存储在关系型数据库中,在nosql数据库中备份关系型数据库的数据。
主流的NOSQL产品 | 存储特点 | 典型应用 | 数据模型 | 优势 | 劣势 |
---|---|---|---|---|---|
Tokyo、Cabinet/Tyrant、Redis、Voldemort、Berkeley、DB | 键值存储数据库 | 使用内存进行缓存,主要用于大量数据的高访问负载 | 键值对 | 查询速度快 | 存储的数据缺少结构化 |
Cassandra、HBase、Riak | 列存储数据库 | 分布式的文件存储系统 | 以列簇式存储,将同一列数据存在一起 | 查找速度快,可扩展性强,更容易进行分布式扩展 | 功能相对来说比较局限 |
CouchDB、MongoDB | 文档型数据库 | Web应用(与Key-Value)类似,Value是结构化的 | 键值对 | 数据结构要求不严格 | 查询性能不高,而且缺乏统一的查询语句 |
Neo4J、InfoGrid、Infinite Graph | 图形数据库 | 社交网络 | 图结构 | 可以结合图结构相关算法 | 需要对整个图做计算才能得出结果,很难做出分布式的集群方案 |
Redis的使用
一、下载安装与使用
官网地址,Redis中文网,Redis的安装非常简单,解压后即可双击直接可以使用。
第一步,先双击启动redis的服务器端,启动成功如下图
第二步,双击启动redis的客户端,启动成功如下图
倘若没有启动服务端,直接就启动客户端,会出现以下这个错误
二、redis的应用场景
- 缓存(数据查询、短连接、新闻内容、商品内容等等)
- 聊天室的在线好友列表
- 任务队列(秒杀、抢购、12306等等)
- 应用排行榜
- 网站访问统计
- 数据过期处理(可以精确到毫秒)
- 分布式集群架构中的session分离
三、redis的数据结构:redis是以key、value的存储格式,其中key都是字符串,value有以下五种不同的数据结构
- 字符串类型 string
- 哈希类型 hash:map格式
- 列表类型 list:linked list格式,支持重复元素。
- 集合类型 set:不允许重复元素。
- 有序集合类型 sorted set:不允许重复元素,且元素有顺序。
四、redis相关的命令操作
- 字符串类型string
- 存储:
set key value
- 获取:
get key
- 删除:
del key
- 哈希类型 hash
- 存储:
hset key field value
- 获取:
hget key field
,用来获取指定的field对应的值 - 获取:
hgetall key
,用来获取所有的filed和value的值 - 删除:
hdel key field
- 列表类型 list:可以添加一个元素到列表的头部(左)或者尾部(右)
- 添加:
lpush key value
,将元素添加到列表的头部。 - 添加:
rpush key value
,将元素添加到列表的尾部。 - 获取:
lrange key start end
,范围获取。 - 删除:
lpop key
,删除列表最左边的元素,并将元素返回。 - 删除:
rpop key
,删除列表最右边的元素,并将元素返回。
- 集合类型 set:不允许重复元素。
- 存储:
sadd key value
- 获取:
smembers key
,获取set集合中所有元素。 - 删除:
srem key value
,删除set集合中的某个元素。
- 有序集合类型 sorted set:不允许重复元素,且元素有顺序,每个元素都会关联一个double类型的数值,redis会通过该数值来为集合中的元素进行从小到大的排序。
- 存储:
zadd key score value
- 获取:
zrange key start end [widhscores]
- 删除:
zrem key value
- 通用命令
keys *:
查询所有的键。type key:
获取键对应的value的类型。del key:
删除指定的key value。clear:
清空客户端屏幕。
五、redis持久化
redis是一个内存数据库,当redis服务器重启时,存在内存的数据就会丢失,但redis提供了数据持久化这种机制,就是可以将数据保存到硬盘中。
- redis持久化机制:可以在redis.windows.conf配置文件中自行配置
- RDB:默认机制,在一定的间隔时间中,检测key的变化情况,然后持久化数据。
- AOF:日志记录方式,可以在每一次命令操作后,持久化数据。
# RDB配置
# after 900 sec (15 min) if at least 1 key changed
save 900 1
# after 300 sec (5 min) if at least 10 keys changed
save 300 10
# after 60 sec if at least 10000 keys changed
save 60 10000
# AOF配置
appendonly no(关闭AOF)
appendonly yes(开启AOF)
# appendfsync always(每一次操作都进行持久化)
appendfsync everysec(每隔一秒进行一次持久化)
# appendfsync no(不进行持久化)
当我们修改完配置文件时,必须得重启redis服务器并指定配置文件名称,因为我们要指定配置文件名称,所以得用cmd命令窗口启动服务器,首先我们先切换到redis的安装目录下,安装目录/redis-server.exe redis.windows.conf
,当我们指定RDB机制启动时,持久化之后会在安装目录下自动生成一个dump.rdb文件,同样,如果我们指定AOF机制启动时,持久化之后会在安装目录下自动生成一个appendonly.aof文件。
Java客户端Jedis
Jedis:是一款java操作的redis数据库的工具,与使用JDBC连接数据库的方式很相似,所以在使用之前,我们需要下载关于Jedis的jar包。
public static void main(String[] args) {
// 在连接redis数据库时,请先打开redis服务器
// 第一个参数为ip地址,第二个参数为端口号。如果使用空参构造器,默认是为localhost,6379端口
// 第一步,获取连接
Jedis jedis = new Jedis("localhost", 6379);
// 第二步,执行操作
jedis.set("username", "zhangsan");
// 第三步,关闭连接
jedis.close();
}
Jdeis常用方法:方法名和命令行名称大致相同
- 字符串类型 string
set(String key, String value):
存储字符串类型的元素。get(String key):
获取指定名称的字符串元素。setex(String key, int seconds, String value):
该方法可以指定生存周期的字符串元素,我们可以应用于验证码的获取。del(String key):
删除指定key的元素。- 哈希类型 hash:map格式
hset(String key, String field, String value):
存储hash类型元素。String hget(String key, String field):
获取指定hash中field对应的value元素。Map<String, String> hgetAll(String key):
获取指定hash所有的元素.hdel(String key, String field):
删除指定hash中field对应的value元素。- 列表类型 list:linkedlist格式,支持重复元素。
lpush(String key, String... vars):
从指定列表中从头部添加一个元素,例如jedis.lpush("mylist","a","b","c")
。rpush(String key, String... vars):
从指定列表中从尾部添加一个元素,例如jedis.rpush("mylist","a","b","c")
。lpop(String key):
从指定列表中从头部弹出一个元素。rpop(String key):
从指定列表中从尾部弹出一个元素。lrange(String key, long start, long end):
从列表中获取指定范围的元素,strat为0,end为-1时则获取全部元素。- 集合类型 set:不允许重复元素
sadd(String key, String... vars):
存储set类型元素,例如jedis.sadd("myset","java","php","c++")
。smembers(String key):
获取集合中所有的元素。srem(String key, String... vars):
删除set集合中指定的元素。- 有序集合类型 sorted set:不允许重复元素 ,且元素可以序列。
zadd(String key, double scorces, String value):
存储有序集合类型元素。zrange(String key, long start, long end):
指定范围查询有序集合中的元素,并且查询出来的元素为已经排序好的。zrem(String key, String... vars):
删除集合中指定的元素。
Jedis连接池:JedisPool
与其他连接池概念大体相同,为了减少由于频繁操作Jedis资源造成程序性能低下,所以便提供了Jedis池化技术,即在JedisPool创建时初始化一下连接资源到池中,使用Jedis连接资源时不需要创建,而是直接从池中获取。当使用完毕后,不需要对该连接资源进行销毁,而是将其归还给连接池,供其他请求使用。
public static void main(String[] args) {
// 创建一个连接池配置对象
JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
// 对连接池进行配置
jedisPoolConfig.setMaxTotal(50);
jedisPoolConfig.setMinIdle(10);
// 创建Jedis连接池对象
JedisPool jedisPool = new JedisPool(jedisPoolConfig, "localhost", 6379);
// 获取连接对象
Jedis jedis = jedisPool.getResource();
jedis.set("username", "zhangsan");
// 归还连接池
jedis.close();
}