建设网站需要了解些什么问题食品包装设计用什么软件

当前位置: 首页 > news >正文

建设网站需要了解些什么问题,食品包装设计用什么软件,p2p网站建设费用,ui设计到底是干嘛的Redis基础知识概述 文章目录 Redis基础知识概述一、Redis简介二、NoSQL技术三、Redis的高并发和快速原因四、Redis为什么是单线程的 五、单线程的优劣势1、优势2、劣势 六、Redis高并发总结七、在java中使用Redis1、添加Jedis依赖 八、Redis在Java Web中的应用1、存储缓存用的数…Redis基础知识概述 文章目录 Redis基础知识概述一、Redis简介二、NoSQL技术三、Redis的高并发和快速原因四、Redis为什么是单线程的 五、单线程的优劣势1、优势2、劣势 六、Redis高并发总结七、在java中使用Redis1、添加Jedis依赖 八、Redis在Java Web中的应用1、存储缓存用的数据2、高速读写场合 九、在spring中使用Redis1、使用spring配置JedisPoolConfig对象2、为连接池配置工厂模型3、配置RedisTemplate4、测试 十、springboot中使用Redis1、在springboot中添加Redis依赖2、添加配置文件application.peoperties3、测试访问4、存储对象 一、Redis简介 1、RedisRemote Dictionary Server 远程字段服务是一个开源的使用ANSI C语言编写、支持网络、科技与内存亦可持久化的日志型、key-value数据库并提供多种语言的API。 2、Redis是一个key-value存储系统它支持存储的value类型相对更多包括string、list、set、zsetsorted set –有序集合和hash。这些数据结构都支持push/pop、add/remove及取交集并集和差集及更丰富的操作而且这些操作都是原子性的。在此基础上Redis支持各种不同方式的排序。为了保证效率数据都是缓存在内存中Redis会周期性的把更新的数据写入磁盘或者把修改操作写入追加的记录文件并且在此基础上实现了master-slave主从同步。 3、Redis提供了java、C/C、PHP、JavaScript、Perl、Object-C、Python、Ruby、Erlang等客户端使用很方便。 4、Reids支持主从同步。数据可以从主服务器向任意数量的从服务器上同步从服务器可以是关联其他服务器的主服务器。这使得Redis可执行单层数复制。存盘可以有意无意的对数据进行写操作。由于完全实现了发布/订阅机制使得从数据库在任何地方同步树时可订阅一个频道并接收主服务器完整的消息发布记录。同步对读取操作的可扩展性和数据冗余很有帮助。 5、 在我们日常的Java Web开发中无不都是使用数据库来进行数据的存储由于一般的系统任务中通常不会存在高并发的情况所以这样看起来并没有什么问题可是一旦涉及大数据量的需求比如一些商品抢购的情景或者是主页访问量瞬间较大的时候单一使用数据库来保存数据的系统会因为面向磁盘磁盘读/写速度比较慢的问题而存在严重的性能弊端一瞬间成千上万的请求到来需要系统在极短的时间内完成成千上万次的读/写操作这个时候往往不是数据库能够承受的极其容易造成数据库系统瘫痪最终导致服务宕机的严重生产问题。 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-tLb9zQWV-1682565151611)(C:\Users\DELL\AppData\Roaming\Typora\typora-user-images\image-20230421095843441.png)] 二、NoSQL技术 为了克服上述问题java web项目通常会引入NoSQL技术这是一种基于内存的数据库并且提供一定的持久化功能。 Redis和MongoDB是当前使用最广泛的NoSQL 而就Redis技术而言它的性能十分优越可以支持每秒十几万的读写操作其性能远超数据库并且还支持集群、。分布式、主从同步等配置原则上可以无限扩展让更多的数据存储在内存中更让人欣慰的是它还支持一定的事务能力这保证了高并发的场景下数据的安全和一致性。 三、Redis的高并发和快速原因 1.Redis是基于内存的内存的读写速度非常快 2.Redis是单线程的省去了很多上下文切换线程的时间 3.Redis使用多路复用技术可以处理并发的连接。非IO内部实现采用epoll采用了epoll自己实现的简单的事件框架。epoll的读写、关闭、连接都转化为事件然后利用epoll的多路复用特性绝不在IO上浪费一点时间。 四、Redis为什么是单线程的 1、官方解释 Redis是基于内存的操作CPU不是Redis的瓶颈Redis的瓶颈最有可能是机器内存的大小或者网络宽带。既然单线程容易实现而且CPU不会成为瓶颈那么顺理成章的采用单线程的方案。 2、详细原因 1不需要各种锁的性能消耗 Redis的数据结构并不全是key-value形式的还有listhash等复杂的结构这些结构有可能会进行很细粒度的操作比如在很长的列表后面添加一个元素在hash中添加或删除一个对象这些操作可能就需要加非常多的锁导致的结果是同步开销大大增加。 总之在单线程的情况下就不用去考虑各种锁的问题不存在加锁和释放锁的操作没有因为可能出现的死锁而导致的性能消耗。 2单线程多进程集群方案 单线程的威力实际上非常强大每核心效率也非常高多线程自然是可以比单线程有更高的性能上限但是在今天的计算环境中即使是单机多线程的上限也往往不能满足需要了需要进一步摸索的是多服务器集群化的方案这些方案中多线程的技术照样是用不上的。 所以单线程、多进程的集群不失为一个时髦的解决方案。 3CPU消耗 采用单线程避免了不必要的上下文切换和竞争条件也不存在多进程或者多线程导致的切换而消耗CPU。 但是如果CPU称为Redis的瓶颈或者不想让服务器其它CPU核闲置那怎么办 可以考虑多起几个Redis进程Redis是key-value数据库不是关系型数据库数据之间没有约束。只要客户端分清哪些key放在哪个Redis进程中就可以了。 五、单线程的优劣势 1、优势 代码更清晰处理逻辑更简单不用考虑各种锁的问题不存在加锁和释放锁的操作没有因为可能出现死锁而导致的性能消耗不存在多线程切换而消耗CPU 2、劣势 无法发挥多核CPU性能优势不过可以通过单击开多个Redis实例来完善。 六、Redis高并发总结 1、Redis是纯内存数据库一般都是简单存取操作线程占用的时间很多时间的花费主要集中在IO上所以读取速度快 2、Redis使用的是非阻塞IOIO多路复用使用了单线程来轮询描述符将数据库的开、关、读、写都转换成事件减少了线程切换时上下文切换和竞争。 3、Redis采用了单线程的模型保证了每个操作的原子性也减少了线程的上下文切换和竞争。 4、Redis全程使用hash结构读取速度快还有一些特殊的数据结构对数据存储进行了优化如压缩表对短数据进行压缩存储再如跳表使用有序的数据结构加快读写的速度。 5、Redis采用自己实现的事件分离器效率比较高内部采用非阻塞的执行方式吞吐能力比较大。 七、在java中使用Redis 1、添加Jedis依赖 想要在 Java 中使用 Redis 缓存需要添加相关的Jar包依赖打开Maven仓库的网站https://mvnrepository.com/ 搜索Jedis 把它导入工程中去就可以啦下面我们来对Redis的写入性能做一下测试 Test public void redisTester() {Jedis jedis new Jedis(localhost, 6379, 100000);int i 0;try {long start System.currentTimeMillis();// 开始毫秒数while (true) {long end System.currentTimeMillis();if (end - start 1000) {// 当大于等于1000毫秒相当于1秒时结束操作break;}i;jedis.set(test i, i );}} finally {// 关闭连接jedis.close();}// 打印1秒内对Redis的操作次数System.out.println(redis每秒操作 i 次); } ———–测试结果———– redis每秒操作10734次2、使用Redis连接池 跟数据库连接池相同Java Redis也同样提供了类 redis.clients.jedis.JedisPool来管理我们的Reids连接池对象并且我们可以使用 redis.clients.jedis.JedisPoolConfig来对连接池进行配置代码如下 JedisPoolConfig poolConfig new JedisPoolConfig(); // 最大空闲数 poolConfig.setMaxIdle(50);// 最大连接数 poolConfig.setMaxTotal(100);// 最大等待毫秒数 poolConfig.setMaxWaitMillis(20000);// 使用配置创建连接池 JedisPool pool new JedisPool(poolConfig, localhost);// 从连接池中获取单个连接 Jedis jedis pool.getResource();// 如果需要密码 //jedis.auth(password);Redis只能支持六种数据结构 string/hash/list/set/zset/hyperloglog的操作 但在Java中我们通常以类对象为主所以在Redis存储的数据结构月java对象之间进行转换如自己编写一些工具类 比如一个角色对象的转换还是比较容易的但是涉及到许多对象的时候这其中无论工作量还是工作难度都是很大的所以总体来说 就操作对象而言使用Redis还是挺难的好在spring对这些进行了封装和支持。 八、Redis在Java Web中的应用 Redis 在 Java Web 主要有两个应用场景 存储缓存用的数据需要高速读写的场合 1、存储缓存用的数据 在日常对数据库的访问中读操作的次数远超写操作比例大概在 1:9 到 3:7所以需要读的可能性是比写的可能大得多的。当我们使用SQL语句去数据库进行读写操作时数据库就会去磁盘把对应的数据索引取回来这是一个相对较慢的过程。 如果放在Redis中也就是放在内存中让服务器直接读取内存中的数据那么速度就会快很多并且会极大减少数据库的压力但是使用内存进行数据存储开销也是比较大的限于成本的原因一般我们只是使用Redis存储一些常用的和主要的数据比如用户登录信息等。 一般而言在使用 Redis 进行存储的时候我们需要从以下几个方面来考虑: 1业务数据常用吗使用率如何 如果使用率较低就没必要写入缓存。 2该业务是读操作多还是写操作多 如果写操作多频繁需要写入数据库也没必要使用缓存。 3业务数据大小如何 如果要存储几百兆字节的文件会给缓存带来很大的压力这样也没必要。 在考虑了这些问题之后如果觉得有必要使用缓存那么就使用它使用 Redis 作为缓存的读取逻辑如下图所示 从上图我们可以知道以下两点 1当第一次读取数据的时候读取Redis的数据就会失败此时就会触发程序读取数据库把数据读取出来并且写入Redis中 2当第二次以及以后需要读取数据时就会直接读取Redis读取数据后就结束了流程这样速度大大提高了。 从上面的分析可以知道读操作的可能性是远大于写操作的所以使用 Redis 来处理日常中需要经常读取的数据速度提升是显而易见的同时也降低了对数据库的依赖使得数据库的压力大大减少。 分析了读操作的逻辑下面我们来看看写操作流程 从流程可以看出更新或者写入的操作需要多个 Redis 的操作如果业务数据写次数远大于读次数那么就没有必要使用 Redis。 2、高速读写场合 在如今的互联网中越来越多的存在高并发的情况比如天猫双11、抢红包、抢演唱会门票等这些场合都是在某一个瞬间或者是某一个短暂的时刻有成千上万的请求到达服务器如果单纯的使用数据库来进行处理就算不崩也会很慢的轻则造成用户体验极差用户量流水重则数据库瘫痪服务宕机而这样的场合都是不允许的 所以我们需要使用 Redis 来应对这样的高并发需求的场合我们先来看看一次请求操作的流程 我们来进一步阐述这个过程 1当一个请求到达服务器时只是把业务数据在Redis上进行读写而没有对数据库进行任何的操作这样就能大大提高读写的速度从而满足高速相应的需求。 2但是这些缓存的数据仍然需要持久化也就是存入数据库之中所以在一个请求操作完Redis的读写之后会去判断该高速读写的业务是否结束这个判断通常会在秒杀商品为0红包金额为0时成立如果不成立则不会操作数据库如果成立则触发事件将Redis的缓存的数据以批量的形式一次性写入数据库从而完成持久化的工作。 九、在spring中使用Redis 上面说到了 Redis 无法操作对象的问题无法在那些基础类型和 Java 对象之间方便的转换但是在 Spring 中这些问题都可以通过使用RedisTemplate得到解决 想要达到这样的效果除了 Jedis 包以外还需要在 Spring 引入 spring-data-redis 包。 1、使用spring配置JedisPoolConfig对象 大部分的情况下我们还是会用到连接池的于是先用 Spring 配置一个 JedisPoolConfig 对象 bean idpoolConfig classredis.clients.jedis.JedisPoolConfig!–最大空闲数–property namemaxIdle value50/!–最大连接数–property namemaxTotal value100/!–最大等待时间–property namemaxWaitMillis value20000//bean2、为连接池配置工厂模型 好了我们现在配置好了连接池的相关属性那么具体使用哪种工厂实现呢在Spring Data Redis中有四种可供我们选择的工厂模型它们分别是 JredisConnectionFactoryJedisConnectionFactoryLettuceConnectionFactorySrpConnectionFactory 我们这里就简单配置成JedisConnectionFactory bean idconnectionFactory classorg.springframework.data.redis.connection.jedis.JedisConnectionFactory!–Redis服务地址–property namehostName valuelocalhost/!–端口号–property nameport value6379/!–如果有密码则需要配置密码–!–property namepassword valuepassword/–!–连接池配置–property namepoolConfig refpoolConfig//bean3、配置RedisTemplate 普通的连接根本没有办法直接将对象直接存入 Redis 内存中我们需要替代的方案将对象序列化可以简单的理解为继承Serializable接口。我们可以把对象序列化之后存入Redis缓存中然后在取出的时候又通过转换器将序列化之后的对象反序列化回对象这样就完成了我们的要求 RedisTemplate可以帮助我们完成这份工作它会找到对应的序列化器去转换Redis的键值 bean idredisTemplateclassorg.springframework.data.redis.core.RedisTemplatep:connection-factory-refconnectionFactory/4、测试 首先编写好支持我们测试的POJO类 /*** author: 素小暖* create: 2020-2-12*/public class Student implements Serializable{private String name;private int age;/** * 给该类一个服务类用于测试*/public void service() {System.out.println(学生名字为 name);System.out.println(学生年龄为 age);}public String getName() {return name;}public void setName(String name) {this.name name;}public int getAge() {return age;}public void setAge(int age) {this.age age;} }然后编写测试类 Test public void test() {ApplicationContext context new ClassPathXmlApplicationContext(applicationContext.xml);RedisTemplate redisTemplate context.getBean(RedisTemplate.class);Student student new Student();student.setName(我没有三颗心脏);student.setAge(21);redisTemplate.opsForValue().set(student_1, student);Student student1 (Student) redisTemplate.opsForValue().get(student_1);student1.service(); }十、springboot中使用Redis 1、在springboot中添加Redis依赖 dependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-data-redis/artifactId /dependency2、添加配置文件application.peoperties

REDIS (RedisProperties)

Redis数据库索引默认为0

spring.redis.database0# Redis服务器地址 spring.redis.hostlocalhost# Redis服务器连接端口 spring.redis.port6379# Redis服务器连接密码默认为空 spring.redis.password# 连接池最大连接数使用负值表示没有限制 spring.redis.pool.max-active8# 连接池最大阻塞等待时间使用负值表示没有限制 spring.redis.pool.max-wait-1# 连接池中的最大空闲连接 spring.redis.pool.max-idle8# 连接池中的最小空闲连接 spring.redis.pool.min-idle0# 连接超时时间毫秒 spring.redis.timeout03、测试访问 RunWith(SpringJUnit4ClassRunner.class) SpringBootTest() public class ApplicationTests {Autowiredprivate StringRedisTemplate stringRedisTemplate;Testpublic void test() throws Exception {// 保存字符串stringRedisTemplate.opsForValue().set(aaa, 111);Assert.assertEquals(111, stringRedisTemplate.opsForValue().get(aaa));} }通过上面这段极为简单的测试案例演示了如何通过自动配置的StringRedisTemplate对象进行Redis的读写操作该对象从命名中就可注意到支持的是String类型。原本是RedisTemplateK, V接口StringRedisTemplate就相当于RedisTemplateString, String的实现。 4、存储对象 这一步跟上面使用Spring一样只需要将POJO类实现Serializable接口就可以了我这里就贴一下测试代码 RunWith(SpringJUnit4ClassRunner.class) SpringBootTest() public class ApplicationTests {Autowiredprivate RedisTemplate redisTemplate;Testpublic void test() throws Exception {User user new User();user.setName(我没有三颗心脏);user.setAge(21);redisTemplate.opsForValue().set(user_1, user);User user1 (User) redisTemplate.opsForValue().get(user_1);System.out.println(user1.getName());} } icationTests {Autowiredprivate RedisTemplate redisTemplate;Testpublic void test() throws Exception {User user new User();user.setName(我没有三颗心脏);user.setAge(21);redisTemplate.opsForValue().set(user_1, user);User user1 (User) redisTemplate.opsForValue().get(user_1);System.out.println(user1.getName());} }