1.redis简介git
在咱们平常的Java Web开发中,无不都是使用数据库来进行数据的存储,因为通常的系统任务中一般不会存在高并发的状况,因此这样看起来并无什么问题。github
但是一旦涉及大数据量的需求,好比一些商品抢购的情景,或者是主页访问量瞬间较大的时候,单一使用数据库来保存数据的系统会由于面向磁盘,磁盘读/写速度比较慢的问题而存在严重的性能弊端,一瞬间成千上万的请求到来,须要系统在极短的时间内完成成千上万次的读/写操做,这个时候每每不是数据库可以承受的,极其容易形成数据库系统瘫痪,最终致使服务宕机的严重生产问题。
为了克服上述的问题,Java Web项目一般会引入NoSQL技术,这是一种基于内存的数据库,而且提供必定的持久化功能。redis
Redis和MongoDB是当前使用最普遍的NoSQL,而就Redis技术而言,它的性能十分优越,能够支持每秒十几万此的读/写操做,其性能远超数据库,而且还支持集群、分布式、主从同步等配置,原则上能够无限扩展,让更多的数据存储在内存中,更让人欣慰的是它还支持必定的事务能力,这保证了高并发的场景下数据的安全和一致性。数据库
Redis 在 Java Web 中的应用
Redis 在 Java Web 主要有两个应用场景:存储缓存用的数据;须要高速读/写的场合使用它快速读/写;
在平常对数据库的访问中,读操做的次数远超写操做,比例大概在 1:9 到 3:7,因此须要读的可能性是比写的可能大得多的。当咱们使用SQL语句去数据库进行读写操做时,数据库就会去磁盘把对应的数据索引取回来,这是一个相对较慢的过程。缓存
若是咱们把数据放在 Redis 中,也就是直接放在内存之中,让服务端直接去读取内存中的数据,那么这样速度明显就会快上很多,而且会极大减少数据库的压力,可是使用内存进行数据存储开销也是比较大的,限于成本的缘由,通常咱们只是使用 Redis 存储一些经常使用和主要的数据,好比用户登陆的信息等。安全
在现在的互联网中,愈来愈多的存在高并发的状况,好比天猫双十一、抢红包、抢演唱会门票等,这些场合都是在某一个瞬间或者是某一个短暂的时刻有成千上万的请求到达服务器,若是单纯的使用数据库来进行处理,就算不崩,也会很慢的,轻则形成用户体验极差用户量流失,重则数据库瘫痪,服务宕机,而这样的场合都是不容许的!
2.redis的下载安装服务器
网站:https://github.com/microsoftarchive/redis/tags
3.redis的基本操做微信
String类型:
存储结构:
redis自身是一个Map,其中全部的数据都是采用key:value的形式存储(key value)
String类型说的是右边的value类型是string类型
基本操做:
添加/修改数据:set key value
获取数据:get key
删除数据:del key
添加/修改多个数据:mset key1 value1 key2 value2
获取多个数据:mget key1 key2 ...
获取数据字符个数:strlen key
追加信息到原始信息的尾部:append key value
扩展操做:
(业务场景:分表时保证主键惟一)
设置数值增长指定范围:incr key
增长指定大小:incrby key increment
设置数值减小指定范围:decr key
减小指定大小:decrby key increment
(业务场景:限时投票)
设置数据具备指定的生命周期:setex key seconds value
注意:
a.单数据操做比多数据操做在必定程度上效率更高
b.string在redis内部默认是一个字符串,当遇到增减类型incr,decr时会转成数值类型进行计算
c.redis全部操做都是原子性的,采用单线程处理全部业务,命令是一个一个执行的。所以无需考虑并发带来的影响
d.按数值进行操做的数据,若是原始数据不能转成数值,或超过了redis数值类型上限,将会报错
string类型的应用场景:
a.微博关注量(在redis中以用户主键和属性做为key)
user:id:123:fans 1232
user:id:123 {id:123,name:吴京,fans:121321}并发
hash类型:
思考:string类型在取值的时候很方便,可是在更新的时候会显得笨重。
存储结构:一个存储空间保存多个键值对数据
例如:key field1 value1 field1 value2
基本操做:
增长修改数据:hset key field value
获取:hget key field/hgetall key
删除数据:hdel key field
添加/修改多个数据:hmset key field1 value1 field2 value2
获取多个数据:hmget key field1 field2
获取hash表中字段的数量:hlen key
获取哈希表中是否存在指定的字段:hexists key field(若是存在field值返回1,不存在返回0)
扩展操做:
获取哈希表中全部的字段名或字段值:hkeys key/hvals key
设置指定字段增长范围:hincrby key increment
有field不让修改,没有加上:hsetnx key field value
注意事项:
a.hash类型的value只能存字符串,不容许存其余类型的值
b.每一个hash能够存储2^32-1个键值对
c.hash类型十分贴近对象的数据存储形式,能够灵活的增删改查对象属性,但hash设计的初衷不是为了存储大量对象的,所以不可将hash做为对象列表使用。
应用场景:
电商购物车设计与实现
购物车商品 商品id:field
商品数量 value
购物车所有商品 hlen获取总量
以用户id做为key,商品编号做为field,数量做为为value进行存储
商品抢购(双11,某商家推出A产品100抢购数量,B产品50,C产品10)
以商家id做为key
参与抢购商品的id做为field
商品数量做为value
以降值的方式控制数量
思考:string和hash均可以存储对象,分别的优缺点?(String偏向总体性,hash偏向灵活性) app
list类型
数据存储需求:存储多个数据,并对存储空间进行顺序的区分
存储结构:一个存储空间保存多个数据,而且可经过顺序获取空间内容,底层使用的是双向链表结构。
基本操做:
增长修改数据:lpush key value1[value2](左进)/rpush key value1[value2](右进)
获取数据:lrange key start
根据下表获取元素:lindex key index
获取长度:llen
获取并移除数据:lpop key/rpop key
扩展操做:
规定时间内获取并移除数据:blpop key timeout/brpop key timeout(阻塞数据获取)
业务场景:
微信 朋友圈点赞,顺序显示点赞好友信息
==》key 朋友圈id value 点赞人
中间有人取消点赞
==》 lrem key count value 删除指定value的数量count
企业运营过程当中,系统将产生大量的运营数据,若是有多态服务器,如何保证信息按统一顺序输出?
==》将多态服务器的信息日志,保存到redis中
注意事项:
a.list中保存的数据都是String类型的,数据总容量有限,最多2^32-1个元素
b.list具备索引的概念,操做数据时一般以队列的形式进行进出操做
c.获取所有数据操做结束索引设置为-1
set类型
思考:存储大量的数据,在查询方面提供更高效的效率?
存储结构:与hash存储结构彻底相同,仅存键值,不存value,而且键值不容许重复。
基本操做:
添加数据:sadd key member1[menmber2]
获取数据:smembers key
删除数据:srem key member1[menmber2]
获取集合数据总量:scard key
判断是否包含指定数据:sismember key member1
扩展操做:
随机获取集合中指定数量的数据:srandmember key[count]
随机获取集合中的某个数据并将该数据移除集合:spop key
两个集合的交,并,差集:sinter key1[key2]/sunion key1[key2]/sdiff key1[key2]
两个集合的交,并,差集存储到指定集合:sinterstore key1[key2]/sunionstore key1[key2]/sdiffstore key1[key2]
业务场景:
1.今日头条在使用时会让用户设置爱好内容,可是后期为了增长用户的活跃度,必须让用户对其余信息也产生兴趣,如何向用户随机推送其余信息呢?
==》系统分析各个分类中最新或者最热的信息,保存到set集合中,而后随机挑选其中的部分信息,配合用户关注的信息分类展现所有信息
2.陌陌为了促进用户交流,如何快速为用户积累跟过的好友?qq推荐共同的好友?
3.黑白名单
信息类网站追求高访问量,经过爬虫快速获取信息,转成商业辛纳希出售,例如:第三方购票软件(获取余票信息),电商刷好评(获取用户信息)
黑名单:屏蔽此类信息
白名单:可访问用户群体
==》将用户信息与黑名单的用户信息比对,在黑名单中不容许访问,再也不放行
注意事项:
set类型不容许数据重复
set虽然与hash结构相同,可是没法启用hash存贮值的空间