要点摘炼Redis篇|JavaEE互联网轻量级框架整合开发

本文涉及的产品
云数据库 Tair(兼容Redis),内存型 2GB
Redis 开源版,标准版 2GB
推荐场景:
搭建游戏排行榜
简介: 学习JavaEE互联网轻量级框架整合开发此书,了解redis这一NoSQL技术,在此做点基础知识简单记录

背景:在传统的Java Web项目中,使用数据库来进行存储数据,但这有一些来自性能方面的弊端。
为什么呢?因为数据库持久化数据主要是面向磁盘,而磁盘的读写比较慢,如果是存在高并发,有瞬间需要读写大量数据的要求的场景(比如即将到来的淘宝双十一,还有抢红包,还有商品抢购场景),一瞬间成千上万的请求发来,需要系统在极短的时间内完成成千上万次的读写操作,这时候就往往不是普通数据库能够承受的了,极其容易造成数据库系统瘫痪,最终导致服务器宕机的严重生产问题。

一、redis介绍

是一种NoSQL技术,NoSQL工具也是一种简易的数据库,主要是一种基于内存的数据库,并提供一定的持久化功能。(PS:MongoDB也是一种NoSQL技术)。redis的性能十分优越,可以支持每秒十几万次的读写操作,并且支持集群、分布式、主从同步等配置,原则上可以无限扩展,让更多的数据存储在内存中,还支持一定的事务能力,这在高并发访问的场景下保证数据安全和一致性特别有用。
从以下三方面体现redis的性能优越性

  • 它是基于ANSI C语言写的,接近于汇编语言,运行十分快速。
  • 它是基于内存的读写,速度自然比数据库的磁盘读写操作快得多。
  • 它的数据库结构只有6中数据类型,数据结构比较简单易用。

redis的常用使用场景

  • 缓存常用的数据,如一些命中率高(即使用频率高)的数据。
  • 在需要高速读写的场合使用它快速读写,比如抢红包和商品抢购的场景。

redis的缓存应用

在数据库的读写操作中,往往是读操作次数远超写操作次数,当发送SQL去数据库进行读取时,数据库就回去磁盘把对应的数据索引取出来,而索引磁盘是一个相对缓慢的过程。如果把数据直接放在运行在内存的Redis服务器上,那么就不再需要去读写磁盘了,直接读取内存,速度就相应得快很多,并且也极大地减轻数据库的压力。

是否使用redis缓存数据的三方面考虑
  • 业务数据常用吗?命中率高?若命中率低就没必要写入缓存。
  • 该业务数据是读操作多还是写操作多,若是需要频繁写入数据库的操作也没必要使用缓存。
  • 业务数据大小如何?如果存储几百兆的文件也没必要使用缓存,会给缓存带来巨大压力。
高速读写场合

如上面说的淘宝的双十一和春运抢票等场景,一瞬间成千上万的请求服务器,这时应对方法往往是考虑异步写入数据库。即先把高速读写的数据缓存到Redis中,在满足一定的条件下,触发这些缓存的数据写入数据库中。
(举例说明:如在商品秒杀的场景把业务数据先在redis中读写,当一个请求操作完redis的读写后,会去判断该高速读写的业务是否结束,比如这里的条件可以是秒杀商品的剩余数为0,此时判断条件成立则触发事件讲redis缓存的数据以批量的形式一次性写入数据库,从而完成持久化的工作。)

二、Redis的安装

①windows上安装
redis下载地址,download下来后解压缩即可,为了方便在解压后的文件里新建一个startup.cmd文件,在里面写上redis-server redis.windows,conf 然后保存,用于快速启动redis,启动的时候直接双击即可。
图片.png
在启动redis后还可以使用解压缩文件里的redis-cli.exe,这是一个redis自带的客户端工具。
图片.png
②linux上安装,这才是实际中最常用的,redis往往安装在服务器端系统。如下步骤:

①使用root用户登录linux系统 即su root "密码"
②在指定目录mkdir新建目录,在切换进入目录
③运行一下命令
 wget http://download.redis.io/releases/redis-3.2.4.tar.gz
 tar xzf redis-3.2.4.tar.gz    //解压文件到当前文件夹的命令
 cd redis-3.2.4  
 make              //安装redis的命令 
④等待片刻,之后在当前目录执行src/redis-server,就可以看到redis启动好了。
⑤在当前目录可以另外打开一个linux窗口,输入src/redis-cli启动redis自带的命令行窗口

三、Redis的6种数据类型

Redis是一种基于内存的数据库,并且提供一定的持久化功能,它是一种键值对数据库,使用key作为索引找到当前缓存的数据。分别有6种数据类型:字符串(String)、列表(List)、集合(set)、哈希结构(hash)、有序集合(zset)、基数(HyperLogLog)。redis定义的这6种数据类型除了可以存储外,还可以对存储的数据进行一些计算。
此外,Redis还支持一些事务、发布订阅消息模式、主从复制、持久化等作为Java程序猿需要知道的功能。

四、Redis的事务

和其他大多数NoSQL不同,Redis是存在事务的。互联网系统面向的是大众,很多用户同时访问,这时系统的性能就很重要的。在Redis中,也存在多个客户端同时向Redis系统发送命令的并发可能性,因此同一个数据,可能在不同的时刻被不同的线程所操纵,这样就出现了并发下的数据一致的问题。为了保证异性数据的安全性,redis提供了事务方案,而redis的事务是使用multi-exec的命令组合,使用它可以提供以下2个保证:
①事务是一个被隔离的操作,事务中方法都会被redis进行序列化并按顺序执行,事务在执行的过程中不会被其他客户端发生的命令打断
②事务是一个原子性的操作,要么全部执行,要么全不执行。
使用spring中会使用SessionCallback接口进行处理,在redis中使用事务会经过3个过程,分别为:①开启事务,②命令进入队列,③执行事务
常用的Redis事务命令:
1、multi(开启事务)
2、watch(监听某个键,当被监听的键在事务执行前被修改,则事务会被回滚)
3、unwatch(取消监听某个键)
4、exec(执行事务,若被监听的键在事务执行前被修改,则事务会被回滚,没有的话则执行命令)
5、discard(回滚进入队列的事务命令,之后不能用exec提交事务)
下图表明开启事务后输入的命令在没有exec执行的时候是一直都存在队列里的。 图片.png

PS:注意一点:Redis在命令入队的时候,就会检查事务的命令是否正确,若不正确则之前之后的命令都会回滚,若事务命令正确则执行。可当命令格式正确,而因为数据结构错误,则该命令执行会报错,而其之前之后的命令都会正常执行,这点就和数据库很不一样。

多线程使用的CAS与乐观锁

当一条线程执行某个业务逻辑,但这条业务逻辑操作的数据被其他线程共享了,这样就会引发线程中数据不一致的情况。为了解决这问题,在读取这些多线程共享的数据时将其保存到当前线程的副本中,成为旧值,之后在执行更新前比较当前线程副本保存的旧值和当前的线程共享的值是否一致,若不一致则更新失败。
由CAS产生而来的ABA问题:即多个线程访问了同一数据,经过一阵修改,改去又改回,最后的值还是和旧值一致,这样redis事务就认为正常事务,但是数据已经被修改过了。

在redis执行事务的过程中,并不会阻塞其他连接的并发,而只是通过比较watch监控的键值对去保证数据的一致性,所以redis多个事务完全可以在非阻塞的多线程环境下并发执行,而且redis的机制是不会产生ABA问题的。

五、Redis总结

Redis和数据库一样可以存储数据,但不代表Redis会取代数据库。有以下原因:
① 虽然NoSQL数据结构比较简单,能处理很多问题,但是其功能毕竟有限,没有SQL语句强大,支持复杂的计算
②NoSQL并不完全安全稳定,由于它基于内存,一旦停电或者机器故障数据就很容易丢失了,而且持久化能力也是有限的
③其数据完整性、事务能力、安全性、可靠性、扩展性都不如数据库
所以,NoSQL和传统数据库各有优势,NoSQL的主要应用场景在于对性能有要求的地方,如果一个系统对性能要求不大,则也没什么必要使用NoSQL技术,传统数据库便可适用。

相关实践学习
基于Redis实现在线游戏积分排行榜
本场景将介绍如何基于Redis数据库实现在线游戏中的游戏玩家积分排行榜功能。
云数据库 Redis 版使用教程
云数据库Redis版是兼容Redis协议标准的、提供持久化的内存数据库服务,基于高可靠双机热备架构及可无缝扩展的集群架构,满足高读写性能场景及容量需弹性变配的业务需求。 产品详情:https://www.aliyun.com/product/kvstore     ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库 ECS 实例和一台目标数据库 RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
相关文章
|
1月前
|
NoSQL Java Redis
redis的基本命令,并用netty操作redis(不使用springboot或者spring框架)就单纯的用netty搞。
这篇文章介绍了Redis的基本命令,并展示了如何使用Netty框架直接与Redis服务器进行通信,包括设置Netty客户端、编写处理程序以及初始化Channel的完整示例代码。
42 1
redis的基本命令,并用netty操作redis(不使用springboot或者spring框架)就单纯的用netty搞。
|
1月前
|
NoSQL Java Redis
shiro学习四:使用springboot整合shiro,正常的企业级后端开发shiro认证鉴权流程。使用redis做token的过滤。md5做密码的加密。
这篇文章介绍了如何使用Spring Boot整合Apache Shiro框架进行后端开发,包括认证和授权流程,并使用Redis存储Token以及MD5加密用户密码。
26 0
shiro学习四:使用springboot整合shiro,正常的企业级后端开发shiro认证鉴权流程。使用redis做token的过滤。md5做密码的加密。
|
1月前
|
NoSQL API Redis
如何使用 C++ 开发 Redis 模块
如何使用 C++ 开发 Redis 模块
|
6月前
|
NoSQL API Redis
最佳实践|如何使用c++开发redis module
本文将试着总结Tair用c++开发redis module中遇到的一些问题并沉淀为最佳实践,希望对redis module的使用者和开发者带来一些帮助(部分最佳实践也适用于c和其他语言)。
76639 0
|
2月前
|
消息中间件 NoSQL Go
PHP转Go系列 | ThinkPHP与Gin框架之Redis延时消息队列技术实践
【9月更文挑战第7天】在从 PHP 的 ThinkPHP 框架迁移到 Go 的 Gin 框架时,涉及 Redis 延时消息队列的技术实践主要包括:理解延时消息队列概念,其能在特定时间处理消息,适用于定时任务等场景;在 ThinkPHP 中使用 Redis 实现延时队列;在 Gin 中结合 Go 的 Redis 客户端库实现类似功能;Go 具有更高性能和简洁性,适合处理大量消息。迁移过程中需考虑业务需求及系统稳定性。
|
4月前
|
NoSQL API Redis
c++开发redis module问题之为什么在使用RedisModule_GetApi之前要通过((void**)ctx)[0]这种方式获取其地址
c++开发redis module问题之为什么在使用RedisModule_GetApi之前要通过((void**)ctx)[0]这种方式获取其地址
|
4月前
|
Rust NoSQL API
c++开发redis module问题之如果在加载module时,该module没有执行权限,Redis会如何解决
c++开发redis module问题之如果在加载module时,该module没有执行权限,Redis会如何解决
|
4月前
|
编解码 NoSQL Redis
c++开发redis module问题之想实现Redis命令,如何解决
c++开发redis module问题之想实现Redis命令,如何解决
|
4月前
|
NoSQL Java 编译器
c++开发redis module问题之保证Redis在fork时没有处于inflight状态的命令,如何解决
c++开发redis module问题之保证Redis在fork时没有处于inflight状态的命令,如何解决
|
4月前
|
NoSQL 编译器 Redis
c++开发redis module问题之如果Redis加载了多个C++编写的模块,并且它们都重载了operator new,会有什么影响
c++开发redis module问题之如果Redis加载了多个C++编写的模块,并且它们都重载了operator new,会有什么影响