锁粒度的粗细与时空损耗互换

1 空间换时间的cases

1.1 redis的用户分组限流和用户定制的限流器

Redis 用户分组限流和用户定制的限流器:使用 Redis 进行用户分组限流或用户定制的限流意味着你使用 Redis 数据库来维护用户的访问限制。可以通过计数器、滑动窗口或令牌桶等算法来实现限流。用户分组限流是为特定的用户组设置限制,而用户定制的限流器是为每个用户设置自定义的限制。

用户分组限流和用户定制的限流器:在 Redis 中维护用户的限流状态需要额外的内存空间,但能快速地检查用户是否达到限流阈值。

1.2 秒杀场景下,设置多个子库存方案与只设置一个总库存方案的对比

秒杀场景下,数据库行锁解决方案:在高并发的秒杀场景下,使用数据库行锁来保证库存数据一致性是非常常见的方法。但是这样只能一个接一个请求去扣减库存,并发性能不太好。

所以可以在数据表中多设置几个子库存,初始时总和等于总库存数,这样当请求来临时可以通过负载均衡策略选择一个子库存进行扣除操作,当某一个子库存扣减为0时关闭到这个库存的路由。

这也是空间换取时间的做法。

1.3 多业务中使用多消息队列或单消息队列

多业务中使用多消息队列或单消息队列:在一个多业务的系统中,使用多个消息队列可以帮助隔离不同的业务流程,提高系统的扩展性和可维护性。而使用单一的消息队列更适合于业务较为简单,或者需要保证消息的全局顺序的场景。

  • 多业务中使用多消息队列或单消息队列:使用多个消息队列意味着需要更多的内存和存储空间来维护这些队列,但能更好地隔离不同的业务流程,同时能够提升并发消费速度。

1.4 HashMap在jdk1.7中的分段锁和1.8中的槽锁

HashMap 在 JDK 1.7 中的分段锁和 JDK 1.8 中的槽锁:在 JDK 1.7 中,ConcurrentHashMap 使用分段锁技术,将数据分成多个段,每个段独立加锁。这样,不同的线程可以同时操作不同的段,提高并发性。在 JDK 1.8 中,ConcurrentHashMap 不再使用分段锁,而是使用了槽锁(synchronized),并引入了红黑树来优化链表的查找性能。

  • HashMap 在 JDK 1.7 中的分段锁和 JDK 1.8 中的槽锁:使用分段锁或槽锁需要额外的内存来维护锁的状态,但能提高 ConcurrentHashMap 的并发性和查找性能。

1.5 redis实现分片计数器

方法:在多个redis实例中设置多个子计数器,每一个请求可以使用负载均衡的策略对某一个计数器进行自增,当需要汇总时把所有这些计数器累加起来。

优点:将计数器分布在多个Redis实例上可以有效地减少单个Redis实例上的压力,并提高总体的并发处理能力。每个Redis实例都可以并行处理请求,从而增加了吞吐量。
缺点:多个计数器会占用更多的内存空间、更多次数的网络IO以及可能存在一致性问题。

2 时间换空间的cases

时间换空间是一种常见的优化策略,它意味着通过花费更多的时间来节省空间。这通常在资源受限的环境中使用,例如在嵌入式系统、移动设备或其他资源受限的环境中。以下是一些常见的使用场景:

  1. 数据压缩:通过压缩数据来节省存储空间,但是这会增加压缩和解压缩所需的时间。

  2. 算法优化:使用更简单的算法来节省空间,但可能会花费更多的时间。例如,选择一个不使用额外空间的排序算法(如冒泡排序),而不是使用额外空间的排序算法(如快速排序)。

  3. 按需计算(单例模式中的懒加载):在需要数据时才进行计算,而不是预先计算和存储结果。例如,可以在需要时计算斐波那契数列的值,而不是预先计算和存储整个序列。

  4. 使用简单的数据结构:使用简单的数据结构(如数组和链表)来节省空间,但可能会增加查找和操作所需的时间。

  5. 数据库规范化:通过数据库规范化来减少数据冗余和节省存储空间,但可能会增加查询复杂性和查询时间。

  6. 在线处理:处理数据的时候,直接从输入流中读取,处理完后直接输出,不存储中间结果。这样可以节省空间,但是如果需要重新处理数据,就需要重新从头开始。

需要注意的是,时间换空间并不总是适用的。在一些场合中,空间可能是更重要的资源,而在其他场合中,时间可能是更重要的资源。所以在决定是否使用时间换空间的策略时,需要根据具体的应用场景和需求来权衡。

猜你喜欢

转载自blog.csdn.net/yxg520s/article/details/132301663