数据库|NoSQL及缓存技术

总结 NoSQL 及缓存技术的知识归纳,工作中 Redis 和 Mongodb 使用场景比较多,以此拓展知识面。


这里写图片描述

1 NoSQL

	NoSQL 是“Not Only SQL”,他不是用来替代关系型数据库的。而是在某些用关系型数据库不合适的地方做优
化的。系统中的常规数据仍然用关系型数据库是最合适。
	常用的 NoSQL 数据库有MemcachedRedisMongoDB 等。RedisMemcached 属于键值
库,MongoDB 属于文档数据库。NoSQL 不是关系型数据库,一般没有 JDBC 驱动,都是用各自数据库的开发包。

2 EhCache

	*EhCache 是一个纯Java的进程内缓存框架,具有快速、精干等特点,是Hibernate 中默
认的 CacheProviderEhcache 是本地缓存(磁盘、内存等)。本地缓存最大的优点就是效率
高。在可预期数据量不大的情况下推荐使用。
	*EhCache 对分布式支持不够好,多个节点不能同步。跨语言使用支持不足。

3 Memcached

	*Memcached 是一个专门用来做缓存的服务器,而且缓存的数据都在内存中。
Memcached 就相当于一个 HashTable 键值对集合,保存的是键值对,然后根据key取 value。
	(1Memcached 服务器的“雪崩”问题:如果所有缓存设置过期时间一样,那么每隔一段时间
就会造成一次数据库访问的高峰。解决的方法就是缓存时间设置不一样,比如加上一个随机数。
	(2Key的长度最高是250个字符,Value最长1M。
	(3)保存普通类对象,则对象必须可序列化。为了跨语言使用,建议保存Json字符串。
	(4Memcaced 就相当于一个大键值对,不同系统放到Memcached中的数据都是不隔离的,
因此设定Key的时候要选择好Key,这样就不容易冲突。建议规则“系统名字_模块名字_业务Key”,
比如“Shop_Admin_FilterWords”。
	(5)ncr、decr 是用来对计数器进行增减的。Redis使用场景更合适。
	(6Memcached 程序重启之后数据就会消失。可对其进行集群和主从同步。

4 Redis

	*Redis是一个支持数据结构更多的键值对数据库。它的值不仅可以是字符串等基本数据类型,也可以是类对象,
**特点:**1)支持string、list、set、zset、hash、geo等复杂的数据结构。
	(2)高命中的数据运行时是在内存中,数据最终还是可以保存到磁盘中,这样服务器重启之后数据还在。
	(3Redis服务器是单线程的,来自所有客户端的所有命令都是串行执行的,因此不用担心并发修改
(串行操作当然还是有并发问题)的问题,编程模型简单;
	(4)支持消息订阅/通知机制,可以用作消息队列;
	(5KeyValue最大长度允许512M;
	(6Redis支持的数据结构:string、list、set、sortedset、hash、geo(redis 3.2以上版本)。
不同数据类型的操作方法不能混用。
	(7Redis服务器默认建了16个数据库,Redis的想法是让大家把不同系统的数据放到不同的数据库中。
但是建议大家不要这样用,因为Redis是单线程的,不同业务都放到同一个Redis实例的话效率就不高,建议
放到不同的实例中。因此尽量只用默认的db0数据库。
	(8Redis还支持MQ特定的“发布/订阅模型”,但是干这个用更专业的MQ服务器更好。
http://www.runoob.com/redis/redis-pub-sub.html
	
	
**操作:**1String类型操作
	del(String... keys):根据一个或者多个Key删除;
	Boolean exists(String key):key是否存在;
	expire(String key, int seconds):单独设置过期时间;
	Set<String> keys(String pattern):根据通配符获取所有匹配的key,尽量不要用,效率低;
	还可以用作计数器:
	incr(String key)给key这个计数器增加一个值,如果不存在则从0开始加;
	decr(String key)计数器减值;获取还是用get(String key)获取字符串类型的值。
	incrby (String key, long integer), decrby(String key, long integer)一次性增加或者减少integer个值。
	案例:计算新闻点击量、点赞量,效率非常高。
(2)list类型操作
	Redis中用List保存字符串集合。 比如可以把聊天记录保存到List中;
商品的物流信息记录。也可以当成双向队列或者双向栈用,list长度是无限。
	lpush(String key, String value)从左侧压栈;
	String lpop(String key)从左侧弹出;
	rpush(String key, String value) 从右侧压栈;
	String rpop(String key) 从右侧弹出;
	如果是读取而不Pop,则使用List<String> lrange(String key, long start, long stop)。
指定之后则获取某个范围,stop=-1则获取所有数据。
	可以把Redis的list当成消息队列使用,比如向注册用户发送欢迎邮件的工作,可以在注册的流程中
把要发送邮件的邮箱放到list中,另一个程序从list中pop获取邮件来发送。
	生产者、消费者模式。把生产过程和消费过程隔离。
(3)set类型操作
	set是一种元素不重复的集合,元素无序。
	sadd(String key, String... members)向set中增加元素
	Set<String> smembers(String key) 获取集合中的元素;
	srem(String key, String... members)从set中删除元素;
	sismember()判断某个值是否在set中;
	注意set不是按照插入顺序遍历的,而是按照自己的一个存储方式来遍历,因为没有保存插入的顺序。
应用案例:使用set保存封禁用户id等,就不用做重复性判断了。
(4)sortedset/zset
	如果对于数据遍历顺序有要求,可以使用sortedset,他会按照打分来进行数据遍历,可以给每项单独打分。
	zadd(String key, double score, String member)在key这个sortedset中增加member,并且给这个
member打分score,如果member已经存在,则覆盖之前的打分;
	double zscore(String key, String member) 获取key中member的打分。
	double zincrby(String key, double score, String member)给key中member这一项增加score分;
如果减分的话给score负值即可。
	Set<String> zrange(String key, long start, long end) 根据升序排序返回sortedset中的元素,
start、end用来分页查询。所以是分数最小的在左边。
	Set<String> zrevrange(String key, long start, long end) 根据降序排序返回sortedset中的
元素,start、end用来分页查询。所以是分数最大的在左边。
	List<ScoredValue<String>> zrangeWithScores(String key, long start, long end)根据升序
排序 返回sortedset中的元素以及元素的打分,start、stop用来分页查询。所以是分数最小的在左边。
	List<ScoredValue<String>> zrevrangeWithScores(String key, long start, long end) 
根据降序排序返回sortedset中的元素以及元素的打分,start、stop用来分页查询。所以是分数最大的在左边。
	sortedset应用场景:
	1)热搜:用户每搜一次一个关键词,就给这个关键词加一分;展示热搜的时候就把前N个获取出来;
	2)高积分用户排行榜;
	3)热门商品;
	4)投票;
(5Hash
	相当于value又是一个“键值对集合”或者值是另外一个键值对。
	hset(final String key, final String field, final String value)String hget(final String key, final String field)等。
(6Geo类型
	GeoRedis 3.2版本后新增的数据类型,用来保存兴趣点(POI,point of interest)的坐标信息。
可以实现计算两POI之间的距离、获取一个点周边指定距离的POI。

5 MongoDB

	MongoDB 是为互联网而生的数据库,是文档数据库。MongoDB 的优点。
	(1Schema-less,不需要预先定义表结构,同一个“表”中可以保存多个格式的数据;
	(2)数据支持嵌套,数据以 JSON 格式存储;
	(3)允许使用JavaScript写服务端脚本,类似于存储过程;
	(4)支持Map/Reduce;
	(5MongoDB支持地理位置索引,可以直接用于位置距离计算和查询,实现“附近的人”、“滴滴打车接单”等很容易;
	
**MongoDB的缺点**:
	(1Mongodb没有“数据一致性检查”、“事务”等,不适合存储对数据事务要求高(比如金融)的数据;
只适合放非关键性数据(比如日志或者缓存)。
	(2)关联查询很弱,不适合做报表查询
	(3)大坑:千万不能用MongoDB代替传统关系型数据库。
	MongoDB只适合存储那些结构不固定(京东不同品类商品的信息)或者嵌套结构复杂(网易新闻的评论)的数。

**查询**
	如果有且只有一行数据,也可以直接用results.first()获取;
	需要注意MongoDB中查询区分大小写;
	查询条件还有eq、ne、gt、lt、gte、lte、in、nin等;
	查询条件还可以进行and、or、not以及复合检索;

**FindIterable**
	skip()/take()分页获取。
	指定排序规则:1是升序,-1是降序。
	相当于order by age asc,height desc。
	当然skip、limit、sort可以一起用。
	FindIterable<Document> results =  
	persons.find().sort(new Document("age",1).append("height", -1));	


**更新数据**
	updateMany第一个参数为过滤条件,第二个为更新算法。
	MongoDB的应用场景很少有需要用到Update的地方,所以不用深入研究。

**删除数据**
	persons.deleteMany(Filters.eq("age", 19));
	deleteMany的参数是删除条件。

**Morphia**
	Morphia是一个框架,类似于ORM框架,封装了对MongoDB的操作,允许通过JavaBean来操作MongoDB。
用Morphia比较适合模型结构比较固定的场景。

**MongoDB应用场景**
	存储“非结构化数据”。
	饿了么外卖骑手接单;存储商品、商家信息;存储爬虫爬过来的第三方数据;
但是像订单、金融交易、游戏装备等这些关键信息不要用MongoDB

6 缓存组件优缺点及使用场景

**Redis优点**:
(1)支持string、list、set、geo等复杂的数据结构;
(2)高命中的数据运行时是在内存中,数据最终还是保存到磁盘中,服务器重启之后数据还在;
(3Redis线程安全,Redis服务器是单线程的,其所有操作都是原子的;
来自所有客户端的所有命令都是串行执行;
(4)支持消息订阅/通知机制,可以用作消息队列;
(5KeyValue最大长度允许512M;
(6Redis的速度非常快(因为使用非阻塞式IO,且大部分命令的算法时间复杂度都是O(1))
总之Redis使用场景更丰富。单机(8G内存)10W/s读性能支持。


**Redis缺点**:
(1Redis是单线程,因此单个Redis实例只能使用一个CPU核,不能充分发挥服务器的性能。
可以在一台服务器上运行多个Redis实例,不同实例监听不同端口,再互相组成集群。
(2)做缓存性能不如Memcached;
(3)使用高耗时的Redis命令很危险,会占用唯一的一个线程的大量处理时间,导致
所有的请求都被拖慢。(例如时间复杂度为O(N)的KEYS命令,严格禁止在生产环境中使用)

**使用场景**:
	(1)会话(Session)缓存 ;
	(2)队列/栈操作,保证分布式系统的顺序性的需求场景;
	(3)排行榜/计数器;
	(4)发布订阅;
	(5)分布式锁;
	http://wudashan.cn/2017/10/23/Redis-Distributed-Lock-Implement/#参考阅读

**Memcached优点**:
(1)多线程,可以充分利用CPU多核的性能;
(2)做缓存性能高;

**Memcached缺点**:
(1)只能保存键值对数据,键值对只能是字符串,如果有对象数据只能自己序列化成json字符串;
2)数据保存在内存中,重启后会丢失;
3)Key最大长度250个字符,Value最长1M。


评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

不甩锅的码农

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值