redis应用场景及实例(为什么要使用Redis)

本文目录
为什么要使用Redis
①Redis定义:
Redis是由意大利人Salvatore Sanfilippo(网名:antirez)开发的一款内存高速缓存数据库。Redis全称为:Remote Dictionary Server(远程数据服务),该软件使用C语言编写,Redis是一个key-value存储系统,它支持丰富的数据类型,如:string、list、set、zset(sorted set)、hash。
② Redis特点
Redis以内存作为数据存储介质,所以读写数据的效率极高,远远超过数据库。以设置和获取一个256字节字符串为例,它的读取速度可高达110000次/s,写速度高达81000次/s。
Redis跟memcache不同的是,储存在Redis中的数据是持久化的,断电或重启后,数据也不会丢失。因为Redis的存储分为内存存储、磁盘存储和log文件三部分,重启后,Redis可以从磁盘重新将数据加载到内存中,这些可以通过配置文件对其进行配置,正因为这样,Redis才能实现持久化。
Redis支持主从模式,可以配置集群,这样更利于支撑起大型的项目,这也是Redis的一大亮点。
③Redis应用场景,它能做什么
众多语言都支持Redis,因为Redis交换数据快,所以在服务器中常用来存储一些需要频繁调取的数据,这样可以大大节省系统直接读取磁盘来获得数据的I/O开销,更重要的是可以极大提升速度。
拿大型网站来举个例子,比如a网站首页一天有100万人访问,其中有一个板块为推荐新闻。要是直接从数据库查询,那么一天就要多消耗100万次数据库请求。上面已经说过,Redis支持丰富的数据类型,所以这完全可以用Redis来完成,将这种热点数据存到Redis(内存)中,要用的时候,直接从内存取,极大的提高了速度和节约了服务器的开销。
总之,Redis的应用是非常广泛的,而且极有价值,真是服务器中的一件利器,所以从现在开始,我们就来一步步学好它。
Redis数据库适合使用于哪些应用场景
redis开创了一种新的数据存储思路,使用redis,我们不用在面对功能单调的数据库时,而是利用redis灵活多变的数据结构和数据操作。
1、首先redis内部使用一个redisobject对象来表示所有的key和value,redisobject最主要的信息如上图所示:type代表一个value对象具体是何种数据类型,encoding是不同数据类型在redis内部的存储方式,比如:type=string代表value存储的是。
2、一个普通字符串,那么对应的encoding可以是raw或者是int,如果是int则代表实际redis内部是按数值型类存储和表示这个字符串的,当然前提是这个字符串本身可以用数值表示,比如:“123““456“这样的字符串。
3、这里需要特殊说明一下vm字段,只有打开了redis的虚拟内存功能,此字段才会真正的分配内存,该功能默认是关闭状态的,该功能会在后面具体描述通过发现redis使用redisobject来表示所有的key/value数据是比较浪费内存的,当然这些内存管理成本的付出主要redis不同数据类型提供一个统一的管理接口,实际作者也提供了多种方法帮助我们尽量节省内存使用,我们随后会具体讨论。
Redis数据库在哪些场景可以应用的到
redis开创了一种新的数据存储思路,使用redis,我们不用在面对功能单调的数据库时,把精力放在如何把大象放进冰箱这样的问题上,而是利用redis灵活多变的数据结构和数据操作,为不同的大象构建不同的冰箱。
redis常用数据类型
redis最为常用的数据类型主要有以下五种:
string
hash
list
set
sorted set
在具体描述这几种数据类型之前,我们先通过一张图了解下redis内部内存管理中是如何描述这些不同数据类型的:
首先redis内部使用一个redisobject对象来表示所有的key和value,redisobject最主要的信息如上图所示:type代表一
个value对象具体是何种数据类型,encoding是不同数据类型在redis内部的存储方式,比如:type=string代表value存储的是
一个普通字符串,那么对应的encoding可以是raw或者是int,如果是int则代表实际redis内部是按数值型类存储和表示这个字符串的,当然
前提是这个字符串本身可以用数值表示,比如:“123“
“456“这样的字符串。
这里需要特殊说明一下vm字段,只有打开了redis的虚拟内存功能,此字段才会真正的分配内存,该功能默认是关闭状态的,该功能会在后面具体描述。通过
上图我们可以发现redis使用redisobject来表示所有的key/value数据是比较浪费内存的,当然这些内存管理成本的付出主要也是为了给
redis不同数据类型提供一个统一的管理接口,实际作者也提供了多种方法帮助我们尽量节省内存使用,我们随后会具体讨论。
下面我们先来逐一的分析下这五种数据类型的使用和内部实现方式:
string
常用命令:
set,get,decr,incr,mget 等。
应用场景:
string是最常用的一种数据类型,普通的key/value存储都可以归为此类,这里就不所做解释了。
实现方式:
string在redis内部存储默认就是一个字符串,被redisobject所引用,当遇到incr,decr等操作时会转成数值型进行计算,此时redisobject的encoding字段为int。
hash
常用命令:
hget,hset,hgetall 等。
应用场景:
我们简单举个实例来描述下hash的应用场景,比如我们要存储一个用户信息对象数据,包含以下信息:
用户id为查找的key,存储的value用户对象包含姓名,年龄,生日等信息,如果用普通的key/value结构来存储,主要有以下2种存储方式:
第一种方式将用户id作为查找key,把其他信息封装成一个对象以序列化的方式存储,这种方式的缺点是,增加了序列化/反序列化的开销,并且在需要修改其中一项信息时,需要把整个对象取回,并且修改操作需要对并发进行保护,引入cas等复杂问题。
第二种方法是这个用户信息对象有多少成员就存成多少个key-value对儿,用用户id+对应属性的名称作为唯一标识来取得对应属性的值,虽然省去了序列化开销和并发问题,但是用户id为重复存储,如果存在大量这样的数据,内存浪费还是非常可观的。
那么redis提供的hash很好的解决了这个问题,redis的hash实际是内部存储的value为一个hashmap,并提供了直接存取这个map成员的接口,如下图:
也就是说,key仍然是用户id,
value是一个map,这个map的key是成员的属性名,value是属性值,这样对数据的修改和存取都可以直接通过其内部map的key(redis里称内部map的key为field),
也就是通过 key(用户id) + field(属性标签)
就可以操作对应属性数据了,既不需要重复存储数据,也不会带来序列化和并发修改控制的问题。很好的解决了问题。
这里同时需要注意,redis提供了接口(hgetall)可以直接取到全部的属性数据,但是如果内部map的成员很多,那么涉及到遍历整个内部map的
操作,由于redis单线程模型的缘故,这个遍历操作可能会比较耗时,而另其它客户端的请求完全不响应,这点需要格外注意。
实现方式:
上面已经说到redis
hash对应value内部实际就是一个hashmap,实际这里会有2种不同实现,这个hash的成员比较少时redis为了节省内存会采用类似一维数组的方式来紧凑存储,而不会采用真正的hashmap结构,对应的value
redisobject的encoding为zipmap,当成员数量增大时会自动转成真正的hashmap,此时encoding为ht。
list
常用命令:
lpush,rpush,lpop,rpop,lrange等。
应用场景:
redis
list的应用场景非常多,也是redis最重要的数据结构之一,比如twitter的关注列表,粉丝列表等都可以用redis的list结构来实现,比较好理解,这里不再重复。
实现方式:
redis
list的实现为一个双向链表,即可以支持反向查找和遍历,更方便操作,不过带来了部分额外的内存开销,redis内部的很多实现,包括发送缓冲队列等也都是用的这个数据结构。
set
常用命令:
sadd,spop,smembers,sunion 等。
应用场景:
redis
set对外提供的功能与list类似是一个列表的功能,特殊之处在于set是可以自动排重的,当你需要存储一个列表数据,又不希望出现重复数据时,set是一个很好的选择,并且set提供了判断某个成员是否在一个set集合内的重要接口,这个也是list所不能提供的。
实现方式:
set 的内部实现是一个
value永远为null的hashmap,实际就是通过计算hash的方式来快速排重的,这也是set能提供判断一个成员是否在集合内的原因。
sorted set
常用命令:
zadd,zrange,zrem,zcard等
使用场景:
redis sorted set的使用场景与set类似,区别是set不是自动有序的,而sorted
set可以通过用户额外提供一个优先级(score)的参数来为成员排序,并且是插入有序的,即自动排序。当你需要一个有序的并且不重复的集合列表,那么可以选择sorted
set数据结构,比如twitter 的public
redis如何理解呢,在哪些方面有应用呢
您好,这样的:
毫无疑问,Redis开创了一种新的数据存储思路,使用Redis,我们不用在面对功能单调的数据库时,把精力放在如何把大象放进冰箱这样的问题上,而是利用Redis灵活多变的数据结构和数据操作,为不同的大象构建不同的冰箱。希望你喜欢这个比喻。
Redis比较适合的一些应用场景,简单列举在这里,供大家一览:
1.取最新N个数据的操作
比如典型的取你网站的最新文章,通过下面方式,我们可以将最新的5000条评论的ID放在Redis的List集合中,并将超出集合部分从数据库获取
使用LPUSH latest.comments《ID》命令,向list集合中插入数据
插入完成后再用LTRIM latest.comments 0 5000命令使其永远只保存最近5000个ID
然后我们在客户端获取某一页评论时可以用下面的逻辑(伪代码)
FUNCTION get_latest_comments(start,num_items):
id_list = redis.lrange(“latest.comments“,start,start+num_items-1)
IF id_list.length 《 num_items
id_list = SQL_DB(“SELECT ... ORDER BY time LIMIT ...“)
END
RETURN id_list
END
如果你还有不同的筛选维度,比如某个分类的最新N条,那么你可以再建一个按此分类的List,只存ID的话,Redis是非常高效的。
2.排行榜应用,取TOP N操作
这个需求与上面需求的不同之处在于,前面操作以时间为权重,这个是以某个条件为权重,比如按顶的次数排序,这时候就需要我们的sorted set出马了,将你要排序的值设置成sorted set的score,将具体的数据设置成相应的value,每次只需要执行一条ZADD命令即可。
3.需要精准设定过期时间的应用
比如你可以把上面说到的sorted set的score值设置成过期时间的时间戳,那么就可以简单地通过过期时间排序,定时清除过期数据了,不仅是清除Redis中的过期数据,你完全可以把Redis里这个过期时间当成是对数据库中数据的索引,用Redis来找出哪些数据需要过期删除,然后再精准地从数据库中删除相应的记录。
4.计数器应用
Redis的命令都是原子性的,你可以轻松地利用INCR,DECR命令来构建计数器系统。
5.Uniq操作,获取某段时间所有数据排重值
这个使用Redis的set数据结构最合适了,只需要不断地将数据往set中扔就行了,set意为集合,所以会自动排重。
6.实时系统,反垃圾系统
通过上面说到的set功能,你可以知道一个终端用户是否进行了某个操作,可以找到其操作的集合并进行分析统计对比等。没有做不到,只有想不到。
7.Pub/Sub构建实时消息系统
Redis的Pub/Sub系统可以构建实时的消息系统,比如很多用Pub/Sub构建的实时聊天系统的例子。
8.构建队列系统
使用list可以构建队列系统,使用sorted set甚至可以构建有优先级的队列系统。
9.缓存
这个不必说了,性能优于Memcached,数据结构更多样化。
Redis应用场景
缓存:这应该是 Redis 最主要的功能了,也是大型网站必备机制,合理地使用缓存不仅可以加 快数据的访问速度,而且能够有效地降低后端数据源的压力。共享Session:对于一些依赖 session 功能的服务来说,如果需要从单机变成集群的话,可以选择 redis 来统一管理 session。
消息队列系统:消息队列系统可以说是一个大型网站的必备基础组件,因为其具有业务 解耦、非实时业务削峰等特性。Redis提供了发布订阅功能和阻塞队列的功 能,虽然和专业的消息队列比还不够足够强大,但是对于一般的消息队列功 能基本可以满足。比如在分布式爬虫系统中,使用 redis 来统一管理 url队列。分布式锁:在分布式服务中。可以利用Redis的setnx功能来编写分布式的锁,虽然这个可能不是太常用。 当然还有诸如排行榜、点赞功能都可以使用 Redis 来实现,但是 Redis 也不是什么都可以做,比如数据量特别大时,不适合 Redis,我们知道 Redis 是基于内存的,虽然内存很便宜,但是如果你每天的数据量特别大,比如几亿条的用户行为日志数据,用 Redis 来存储的话,成本相当的高。

更多文章:
eva是什么材质和橡胶哪个好(鞋子eva复合底与橡胶底哪个好)
2026年10月16日 06:30
linux中shutdown命令(linux 下的关机命令是怎么用的)
2026年10月16日 06:10
框架结构设计步骤是什么?试述在框架设计时,其内力组合一般应考虑哪些组合
2026年10月16日 04:50
layui文件上传(layui文件上传 不兼容ie8怎么解决)
2026年10月16日 02:00







