您的位置:首页 > 财经 > 金融 > 网站开发软件公司_南京小视科技是干什么的_微信如何投放广告_网页怎么做

网站开发软件公司_南京小视科技是干什么的_微信如何投放广告_网页怎么做

2024/12/23 6:34:26 来源:https://blog.csdn.net/qq_42190530/article/details/144651152  浏览:    关键词:网站开发软件公司_南京小视科技是干什么的_微信如何投放广告_网页怎么做
网站开发软件公司_南京小视科技是干什么的_微信如何投放广告_网页怎么做

一、Redis 简介

一、Redis 简介

Redis(Remote Dictionary Server),即远程字典服务,是一款开源的高性能键值对数据库。在当今的数据库领域,Redis 占据着极为重要的地位,以其独特的优势被广泛应用于众多场景。

Redis 的高性能主要源于其基于内存存储数据的特性。内存的读写速度相较于传统硬盘快了几个数量级,这使得 Redis 能够在极短的时间内响应客户端的请求,实现快速的数据读写操作。例如,在处理高频次的网页访问计数场景中,Redis 能够迅速更新和读取页面的访问次数,大大提升了系统的响应速度和用户体验。

同时,Redis 支持多种数据结构,如字符串(String)、列表(List)、集合(Set)、有序集合(Sorted Set)、哈希(Hash)等。这种丰富的数据结构支持使得 Redis 可以适用于各种复杂的数据处理需求。例如,利用列表结构可以轻松实现消息队列功能,有序集合则在排行榜应用场景中发挥出色。此外,Redis 还具备持久化功能,能够将数据定期保存到磁盘上,以防止数据丢失,确保数据的安全性和可靠性。

二、Redis 核心数据结构之 String

二、Redis 核心数据结构之 String

2.1 特性与编码

String 是 Redis 中最基本的数据类型,它具有二进制安全的特性,这意味着它可以存储任意格式的数据,无论是文本、数字、图片还是序列化后的对象等。与 C 语言中的字符串不同,Redis 的 String 是一种动态字符串,其长度可以根据实际存储的数据动态调整。

在内部编码方面,String 主要有三种编码方式。当存储的数字可以用 long 类型表示时,会采用 int 编码,这种编码方式在存储和读取数字时效率极高。例如,当我们使用 Redis 存储用户的年龄、商品的库存数量等整数数据时,就可能会采用 int 编码。embstr 编码则是将字符串对象和其序列化后的字符串值一起存储在一块连续的内存空间中,这种编码方式适用于较短的字符串,它的创建和释放速度都比较快。而 raw 编码则用于存储较长的字符串,它会使用一块单独的内存空间来存储字符串值,并且通过一个指针指向该内存空间。

2.2 操作命令示例

String 类型拥有丰富的操作命令。例如,SET 命令用于设置指定键的值,如 “SET username 'John'”,就将键 “username” 的值设置为 “John”。GET 命令则用于获取指定键的值,执行 “GET username”,就会返回 “John”。

INCR 命令可以对存储的数字值进行原子性的递增操作,比如我们要统计网站的访问次数,每次有访问时就可以使用 “INCR page_views”,Redis 会自动将键 “page_views” 对应的值加 1。与之对应的 DECR 命令则是进行递减操作。

此外,还有 SETNX 命令,它的作用是当且仅当键不存在时才设置键的值,这在实现分布式锁等场景中非常有用。例如 “SETNX lock_key 1”,如果 “lock_key” 不存在,就设置成功并返回 1,否则返回 0,表示获取锁失败。

2.3 应用场景解析

在缓存场景中,String 类型被广泛应用。由于其能够快速地存储和读取数据,将热点数据存储为 String 类型的键值对,可以大大减轻后端数据库的压力,提高系统的整体性能。例如,将频繁访问的网页内容缓存到 Redis 中,下次访问时直接从 Redis 获取,减少了数据库查询和页面渲染的时间。

对于计数器功能,如文章的点赞数、视频的播放次数等,INCR 和 DECR 命令可以方便地实现原子性的计数操作。其优势在于操作的原子性,即使在高并发的情况下,也能保证计数的准确性。

在分布式锁方面,SETNX 命令发挥着关键作用。在分布式系统中,多个进程可能会同时访问共享资源,通过使用 SETNX 命令来获取锁,可以确保同一时间只有一个进程能够访问共享资源,从而避免数据冲突和不一致的问题。

存储配置信息也是 String 类型的常见应用场景。将系统的各种配置参数以键值对的形式存储在 Redis 中,方便在系统运行过程中快速读取和修改配置信息,而且由于 Redis 的持久化功能,即使系统重启,配置信息也不会丢失。

三、Redis 核心数据结构之 List

三、Redis 核心数据结构之 List

3.1 数据结构特点

List 是 Redis 中的双向链表结构,这一特性使得它在插入和删除元素时具有很高的效率。无论是在表头还是表尾进行插入或删除操作,都能在常数时间内完成。例如,在处理实时消息推送系统中的新消息插入时,List 能够快速地将新消息添加到消息队列的头部或尾部。

然而,与插入和删除操作的高效性相比,List 在查找元素方面相对较慢。因为在链表中查找特定元素需要遍历链表,时间复杂度为 O (n)。这与数组等数据结构不同,数组可以通过索引直接定位元素,时间复杂度为 O (1)。但正是由于其链表的特性,List 在内存中的存储并不需要连续的空间,这使得它在存储一些动态变化的数据集合时具有一定的优势,比如在处理不确定长度的任务队列时,List 可以灵活地调整大小。

3.2 操作命令示例

Redis 为 List 提供了丰富的操作命令。LPUSH 命令用于将一个或多个元素插入到列表的头部。例如:

 

LPUSH mylist "element1" "element2"

这将把 "element1" 和 "element2" 依次插入到名为 "mylist" 的列表头部。

RPUSH 命令则是将元素插入到列表的尾部,如:

 

RPUSH mylist "element3"

此时,"element3" 被添加到 "mylist" 的尾部。

LPOP 命令用于移除并返回列表头部的元素:

 

LPOP mylist

执行后将返回 "element2" 并从列表中移除。

RPOP 命令类似地移除并返回列表尾部的元素:

 

RPOP mylist

会返回 "element3"。

LRANGE 命令用于获取列表中指定范围内的元素,例如:

 

LRANGE mylist 0 -1

将返回整个 "mylist" 列表中的所有元素。

3.3 应用场景解析

List 在消息队列场景中有广泛的应用。生产者可以使用 RPUSH 命令将消息添加到队列的尾部,消费者则使用 LPOP 命令从队列头部获取消息进行处理。这种先进先出(FIFO)的特性符合消息队列的处理逻辑。例如在电商系统中,订单处理任务可以放入消息队列,多个消费者进程可以从队列中获取任务并处理,实现订单的异步处理,提高系统的吞吐量。

在栈的应用场景中,LPUSH 和 LPOP 命令可以实现栈的功能。将元素 LPUSH 到列表中,然后 LPOP 出的元素就是后进先出(LIFO)顺序,类似于栈的操作。比如在函数调用栈的模拟中,可以利用 List 来实现。

对于队列功能,除了消息队列这种典型应用,还可以用于任务调度队列等。将需要执行的任务依次 RPUSH 到队列中,然后由工作进程 LPOP 任务进行处理。

在信息流展示方面,List 可以存储一系列的信息元素,如新闻资讯、社交动态等。通过 LRANGE 命令可以按照一定的顺序获取并展示这些信息,例如按照时间顺序展示最新的社交动态。然而,List 在处理大规模数据的信息流时可能会面临性能问题,因为查找特定信息较慢,所以对于需要频繁搜索特定信息的场景可能不太适用,此时可能需要结合其他数据结构如有序集合等来优化。

四、Redis 核心数据结构之 Hash

4.1 结构与编码

Hash 在 Redis 中类似于 Java 中的 HashMap,是一种用于存储键值对集合的数据结构。它可以将多个相关的字段和值组织在一起,方便对对象进行存储和操作。例如,在存储用户信息时,可以将用户名、密码、年龄等信息作为不同的字段存储在一个 Hash 中。

Hash 的内部编码有两种:ziplist 和 hashtable。当 Hash 中元素较少且元素的长度较短时,Redis 会使用 ziplist 编码。ziplist 是一种紧凑的压缩列表,它在内存中占用的空间较小,能够有效地节省内存资源。然而,当 Hash 中的元素数量增多或者元素的长度较长时,ziplist 的性能会受到影响,此时 Redis 会自动将编码转换为 hashtable。hashtable 是一种基于哈希表实现的数据结构,它能够快速地进行插入、删除和查找操作,但相对 ziplist 来说,内存占用会稍大一些。

4.2 操作命令示例

Hash 类型提供了一系列操作命令。例如,HSET 命令用于向 Hash 中设置指定字段的值,如 “HSET user:1 username 'Alice' password '123456'”,这里将用户 ID 为 1 的用户信息存储到了名为 “user:1” 的 Hash 中,设置了 “username” 字段为 “Alice”,“password” 字段为 “123456”。

HGET 命令则用于获取 Hash 中指定字段的值,执行 “HGET user:1 username”,就会返回 “Alice”。

HMSET 命令可以一次性设置多个字段的值,如 “HMSET user:2 username 'Bob' age 25”,同时设置了 “user:2” 这个 Hash 的 “username” 字段为 “Bob”,“age” 字段为 25。

HGETALL 命令用于获取 Hash 中的所有字段和值,例如 “HGETALL user:1”,将返回 “username”、“Alice”、“password”、“123456” 等所有字段和对应的值。

4.3 应用场景解析

Hash 在存储对象场景中表现出色。与 String 类型存储对象相比,Hash 可以将对象的各个属性分别存储为不同的字段,这样在获取或修改对象的某个属性时更加方便和高效。例如,在存储商品信息时,使用 Hash 可以将商品的名称、价格、库存等属性分别存储,当需要更新商品价格时,只需要使用 HSET 命令修改 “price” 字段的值即可,而如果使用 String 类型存储商品对象,可能需要先获取整个对象,修改后再重新存储,效率较低。

在购物车功能实现中,Hash 也有着广泛的应用。可以将每个用户的购物车信息存储为一个 Hash,商品 ID 作为字段,商品数量等信息作为值。这样可以方便地添加、删除商品,以及统计购物车中商品的数量和总价等信息。

对于缓存对象属性的场景,Hash 同样适用。比如在缓存用户的详细信息时,将用户的各种属性以 Hash 的形式缓存起来,能够提高缓存的利用率和数据操作的灵活性,减少不必要的数据传输和存储开销。

五、Redis 核心数据结构之 Set

5.1 特性与功能

Set 是 Redis 中的集合数据结构,它具有无序性和唯一性的特点。无序性意味着 Set 中的元素没有特定的顺序,无论元素是何时插入的,在获取 Set 中的元素时,其顺序都是不确定的。而唯一性则保证了 Set 中不会存在重复的元素,这使得 Set 在处理需要去重的数据集合时非常有用。

Set 支持多种操作,如添加元素、删除元素、判断元素是否存在于集合中、获取集合中的所有元素等。这些操作使得 Set 能够在许多场景中发挥重要作用,例如在数据的去重处理、集合运算以及社交关系模型中的关注列表、标签管理等方面。

5.2 操作命令示例

Redis 为 Set 提供了丰富的操作命令。例如,SADD 命令用于向 Set 中添加一个或多个元素,如下所示:

 

SADD myset "element1" "element2" "element3"

上述命令将 "element1"、"element2" 和 "element3" 添加到名为 "myset" 的 Set 集合中。如果其中某个元素已经存在于集合中,Redis 会自动忽略该元素,因为 Set 的唯一性特性。

SREM 命令用于从 Set 中删除指定的元素,例如:

 

SREM myset "element2"

这将从 "myset" 集合中移除 "element2"。

SMEMBERS 命令可以获取 Set 中的所有元素,执行以下命令:

 

SMEMBERS myset

将返回 "myset" 集合中的所有元素,不过由于 Set 的无序性,每次返回的元素顺序可能不同。

SISMEMBER 命令用于判断一个元素是否存在于 Set 中,如:

 

SISMEMBER myset "element1"

如果 "element1" 存在于 "myset" 集合中,该命令将返回 1,否则返回 0。

5.3 应用场景解析

在抽奖活动场景中,Set 可以用于存储参与抽奖的用户 ID。由于 Set 的唯一性,不会出现同一个用户 ID 被重复添加的情况,保证了抽奖的公平性。在抽奖时,可以使用 SRANDMEMBER 命令从 Set 中随机抽取一个或多个元素作为中奖者,例如:

 

SRANDMEMBER myset 1

上述命令将从 "myset" 集合中随机抽取一个元素作为中奖者。

在用户点赞、收藏功能中,Set 可以用来存储用户点赞或收藏的文章 ID、商品 ID 等。这样可以方便地判断用户是否已经点赞或收藏了某个特定的对象,同时也可以快速获取用户所有的点赞或收藏列表。例如,使用 SISMEMBER 命令判断用户是否点赞了某篇文章,使用 SMEMBERS 命令获取用户的所有点赞文章列表。

对于标签功能,Set 可以表示一个对象的所有标签。例如,一篇文章可以有多个标签,如 "科技"、"互联网"、"创新" 等,这些标签可以存储在一个 Set 中。通过对不同文章的标签 Set 进行交集、并集等集合运算,可以实现相关文章的推荐功能。比如,找出具有相同标签的文章推荐给用户,或者找出所有文章的热门标签等。

在微博、微信等社交平台的关注模型中,Set 可以用来存储用户的关注列表。每个用户的关注列表就是一个 Set,其中包含了该用户关注的其他用户 ID。通过集合运算,可以实现共同关注、粉丝列表等功能。例如,通过求两个用户关注列表的交集,可以得到他们的共同关注对象;通过求某个用户关注列表的补集,可以得到该用户的潜在粉丝列表等。

六、Redis 核心数据结构之 ZSet

6.1 有序集合原理

Redis 的 ZSet(有序集合)是一种非常实用的数据结构,它和 Set 集合有一些相同点,集合中的每一个成员都是字符串类型,并且不允许重复元素存在。但它们最大的区别在于有序集合是有序的,而 Set 是无序的。

ZSet 之所以能够实现有序性,是因为其中的每个成员都会关联一个 double(双精度浮点数)类型的 score(分数值),Redis 正是通过这个 score 来实现对集合成员的排序。例如在 QQ 音乐排行榜、用户贡献榜等类似的排行榜业务场景中,ZSet 就能发挥出色作用。我们可以将歌曲的点击次数作为 score 值,把歌曲的名字作为成员值,通过对 score 排序就可以得出歌曲 “热度榜单”。

在底层数据结构实现方面,ZSet 使用了两种不同的存储结构,分别是 zipList(压缩列表)和 skipList(跳跃列表)。当 ZSet 满足成员的数量小于 128 个,并且每个成员的字符串长度都小于 64 个字节这两个条件时,会使用压缩列表来保存数据。压缩列表由 zlbytes(表示当前 ziplist 占用的总字节数)、zltail(指的是压缩列表尾部元素相对于压缩列表起始元素的偏移量)、zllen(指 ziplist 中 entry 的数量)、entry(用来存放具体的数据项,即 score 和 member,长度不定,可以是字节数组或整数,会根据成员的数量自动扩容)以及 zlend(一个单字节的特殊值,等于 255,起到标识 ziplist 内存结束点的作用)这五部分组成,且每一部分在内存中都是紧密相邻的。在压缩列表中,entry 的第一个节点保存 member,第二个节点保存 score,集合中的所有成员最终会按照 score 从小到大排列。

而当有序集合不满足使用压缩列表的条件时,就会使用 skipList 结构来存储数据。跳跃列表(skipList)又称 “跳表”,是一种基于链表实现的随机化数据结构,其插入、删除、查找的时间复杂度均为 O (logN)。跳跃列表中的每一层都是一个有序的链表,链表中每个节点都包含两个指针,一个指向同一层的下一个节点,另一个指向下一层的同一个节点,最低层的链表将包含 ZSet 中的所有元素。如果一个元素出现在了某一层,那么低于该层的所有层都将包含这个元素,也就是说高层是底层的子集。

6.2 操作命令示例

ZSet 有着丰富的操作命令,下面来介绍一些常用的命令及示例:

  • ZADD:用于向有序集合中添加一个或多个成员及对应的分数值。例如:
 

ZADD myzset 10 "member1" 20 "member2"

上述命令将成员 "member1"(分数为 10)和 "member2"(分数为 20)添加到名为 "myzset" 的有序集合中。如果添加的成员已存在,则会更新其对应的分数,并重新按照分数对集合成员进行排序。

  • ZRANGE:可以按照索引范围查询有序集合中的成员。例如:
 

ZRANGE myzset 0 2

这条命令会返回 "myzset" 有序集合中索引从 0 到 2 的成员,默认是按照分数从小到大的顺序返回。如果想连同分数一起返回,可以使用 "WITHSCORES" 参数,像这样:

 

ZRANGE myzset 0 2 WITHSCORES

  • ZREM:用于从有序集合中删除指定的成员。例如:
 

ZREM myzset "member1"

执行后会将 "member1" 从 "myzset" 有序集合中移除。

  • ZSCORE:能够获取指定成员在有序集合中的分数值。比如:
 

ZSCORE myzset "member2"

该命令会返回 "member2" 在 "myzset" 有序集合中的分数,也就是 20。

6.3 应用场景解析

ZSet 在很多实际应用场景中都有着广泛的应用,尤其在需要排序和范围查询功能的场景下优势明显。

  • 排行榜场景:例如常见的游戏排行榜、微博热搜榜、百度热榜等,都可以使用 ZSet 来实现。以游戏排行榜为例,将玩家的 ID 作为成员,玩家的游戏得分或者等级等作为分数值,通过 ZSet 的排序功能,就可以轻松获取分数排名靠前的玩家信息,展示出排行榜。而且当玩家的分数发生变化时,利用 ZADD 等命令更新对应的分数值,ZSet 会自动重新排序,始终保持排行榜的准确性。
  • 新闻排名场景:在新闻类网站中,根据新闻的热度(如点击量、评论量等)对新闻进行排名展示。可以把新闻标题作为成员,对应的热度数值作为分数,借助 ZSet 实现按照热度高低对新闻进行排序,方便用户快速浏览热门新闻内容。同时,随着新闻热度的变化,通过相应命令更新分数,排行榜也能实时更新,为用户呈现最新的热门新闻情况。

总之,ZSet 的排序和范围查询功能使其在诸多需要对数据进行动态排序展示的场景中,成为了非常理想的数据结构选择。

七、Redis 数据结构的选择与应用策略

在实际项目中,选择合适的 Redis 数据结构对于优化系统性能、满足业务需求至关重要。这需要综合考虑多方面因素,包括数据特点、性能需求以及业务场景等。

首先,分析数据特点是选择数据结构的基础。如果数据是简单的文本、数字或二进制数据,且不需要进行复杂的内部结构管理,String 类型通常是首选。例如,存储单个用户的登录令牌、配置参数等信息,String 能够高效地完成存储和读取操作。若数据具有关联性,类似对象的多个属性,Hash 则更为合适。如存储用户详细信息,将用户名、密码、年龄等作为 Hash 的字段,可以方便地对单个属性进行操作,提高数据处理的灵活性。

性能需求方面,不同操作在不同数据结构上的时间复杂度差异显著。对于频繁的插入和删除操作,如果对顺序没有严格要求,Set 和 Hash 的性能表现较好。Set 的无序性和唯一性使其在处理去重数据集合时效率很高,例如存储用户的唯一标识集合。而 Hash 在更新特定字段时具有优势,如更新用户信息中的某个属性。如果需要快速的插入和删除头部或尾部元素,List 的双向链表结构则能满足需求,像消息队列场景中的消息添加和移除操作。对于排序和范围查询操作,ZSet 则是不二之选,其基于 score 的排序功能能够高效地实现排行榜等功能,如游戏排行榜中根据玩家得分进行排名和查询。

业务场景适配也是关键因素。在消息队列场景中,List 的先进先出特性符合消息处理的顺序要求,可用于任务调度、事件处理等异步任务流程。Set 在数据去重场景下表现出色,如抽奖活动中的用户去重、标签管理中的标签去重等。ZSet 则广泛应用于需要动态排序展示的场景,如新闻热度排名、社交媒体的影响力排名等。

综上所述,在选择 Redis 数据结构时,需要全面深入地分析数据的性质、业务的具体需求以及对性能的期望,通过综合权衡这些因素,做出最为恰当的选择,从而充分发挥 Redis 在数据处理和存储方面的强大优势,提升系统的整体性能和响应速度,为业务的稳定高效运行提供有力支持。

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com