令Redis运行更稳定:缓存二进制数据
Redis 是一个基于内存的数据结构存储系统,具有快速读写的能力。它支持多种数据类型,如字符串、哈希、列表等,而且它在许多应用场景下都能提供高性能的解决方案。但是在某些场合下,由于 Redis 数据过大,或者字节数据包含特殊字符等,会导致 Redis 出现运行不稳定的情况。因此,我们需要了解如何使用 Redis 缓存二进制数据,以提高 Redis 运行的可靠性。

Redis 默认情况下只支持字符串类型存储,这意味着如果要存储二进制数据,它必须被编码字符串形式。但是,在某些场景下,比如存储图片、音频、视频等大型数据,以字符串形式存储会导致 Redis 实例负载急剧上升。此外,这些数据可能包含二进制字符,这会导致读取和解析数据变得非常困难。
为了解决这个问题,我们可以使用 Redis 的二进制数据类型,比如 Redis Bitmaps 或 Redis Streams 等。这些数据结构提供了直接存储二进制数据的能力,因此可大大提高 Redis 在处理数据时的效率和稳定性。
下面以 Redis Bitmaps 为例,演示如何在 Redis 中使用二进制数据类型。
代码样例:
import redis
r = redis.Redis(host=’localhost’, port=6379, db=0)
# 添加一个 10 字节的二进制数据到 bitmap
r.setbit(‘mybitmap’, 0, 1)
r.setbit(‘mybitmap’, 1, 0)
r.setbit(‘mybitmap’, 2, 1)
r.setbit(‘mybitmap’, 3, 0)
r.setbit(‘mybitmap’, 4, 1)
r.setbit(‘mybitmap’, 5, 0)
r.setbit(‘mybitmap’, 6, 1)
r.setbit(‘mybitmap’, 7, 0)
r.setbit(‘mybitmap’, 8, 1)
r.setbit(‘mybitmap’, 9, 0)
# 获取bitmap中第2个字节
print(r.getrange(‘mybitmap’, 1, 1))
# 获取bitmap中第3 ~ 9个字节
print(r.getrange(‘mybitmap’, 2, 8))
在上面的示例中,我们使用 Redis Bitmaps 存储了一个 10 字节的二进制数据。在存储数据时,我们使用了 Redis 的 setbit() 方法,该方法可以将 bitmap 中的某个比特位设置为 1 或 0。在读取数据时,我们使用了 Redis 的 getrange() 方法,该方法可以获取 bitmap 中的指定字节范围内的数据。使用 Redis Bitmaps,我们可以很容易地存储和读取二进制数据。不仅如此,它还可以让我们使用位运算来对数据进行操作,例如计算二进制数据中包含的 1 的个数、计算二进制数据中第一个 1 的位置等。这些操作能够更加高效地完成,而且不需要在中间过程中进行字符串到二进制的转换。当然,使用 Redis 的二进制数据类型并不是一个银弹,它们并不能解决所有的问题。比如流数据等大型数据类型无法直接使用 Redis Bitmaps 进行存储。但是,通过选择合适的 Redis 数据类型,我们可以更好地优化 Redis 的性能和稳定性,并愉快地使用 Redis 服务。在本文中,我们探讨了如何使用 Redis 的二进制数据类型,以使 Redis 运行更加稳定。我们看到 Redis 为我们提供了许多强大的数据结构,以应对不同类型的数据存储挑战。但是,我们需要理解每个数据类型的优点和限制,以便选择最适合我们应用场景的结构。
香港服务器首选树叶云,2H2G首月10元开通。树叶云(shuyeidc.com)提供简单好用,价格厚道的香港/美国云 服务器 和独立服务器。IDC+ISP+ICP资质。ARIN和APNIC会员。成熟技术团队15年行业经验。
executeQuery();和addBatch();executeBatch();除了执行单个和批量处理的不同外,还有什么不同?
executeQuery()是专门用来执行DQL(就是数据查询语句SELECT)语句的;而addBatch()和executeUpdate()是用来执行数据插入的,不同就是一个批量,一个单个插入。 这两个不要一起使用,那样addBatch()就和没写一样。 addBatch()是用来缓存数据的,将多条sql语句缓存起来,再通过executeBatch()方法一次性发给数据库,大大提高执行效率。 executeUpdate()注重的及时性,每写一条sql语句就发送给数据库保存起来,没有缓存,这样频繁操作数据库效率非常低。 还有一点需要注意的是:使用addBatch()缓存数据时要在循环中设置条件,当循环达到指定次数后执行executeBatch(),将缓存中的sql全部发给数据库,然后执行clearBatch()清楚缓存,否则数据过大是会出现OutOfMemory(内存不足)。
memcached和redis的区别
medis与Memcached的区别传统MySQL+ Memcached架构遇到的问题 实际MySQL是适合进行海量数据存储的,通过Memcached将热点数据加载到cache,加速访问,很多公司都曾经使用过这样的架构,但随着业务数据量的不断增加,和访问量的持续增长,我们遇到了很多问题: 需要不断进行拆库拆表,Memcached也需不断跟着扩容,扩容和维护工作占据大量开发时间。 与MySQL数据库数据一致性问题。 数据命中率低或down机,大量访问直接穿透到DB,MySQL无法支撑。 4.跨机房cache同步问题。 众多NoSQL百花齐放,如何选择 最近几年,业界不断涌现出很多各种各样的NoSQL产品,那么如何才能正确地使用好这些产品,最大化地发挥其长处,是我们需要深入研究和思考的问题,实际归根结底最重要的是了解这些产品的定位,并且了解到每款产品的tradeoffs,在实际应用中做到扬长避短,总体上这些NoSQL主要用于解决以下几种问题 1.少量数据存储,高速读写访问。 此类产品通过数据全部in-momery 的方式来保证高速访问,同时提供数据落地的功能,实际这正是Redis最主要的适用场景。 2.海量数据存储,分布式系统支持,数据一致性保证,方便的集群节点添加/删除。 3.这方面最具代表性的是dynamo和bigtable 2篇论文所阐述的思路。 前者是一个完全无中心的设计,节点之间通过gossip方式传递集群信息,数据保证最终一致性,后者是一个中心化的方案设计,通过类似一个分布式锁服务来保证强一致性,数据写入先写内存和redo log,然后定期compat归并到磁盘上,将随机写优化为顺序写,提高写入性能。 free,auto-sharding等。 比如目前常见的一些文档数据库都是支持schema-free的,直接存储Json格式数据,并且支持auto-sharding等功能,比如mongodb。 面对这些不同类型的NoSQL产品,我们需要根据我们的业务场景选择最合适的产品。 Redis适用场景,如何正确的使用 前面已经分析过,Redis最适合所有数据in-momory的场景,虽然Redis也提供持久化功能,但实际更多的是一个disk-backed的功能,跟传统意义上的持久化有比较大的差别,那么可能大家就会有疑问,似乎Redis更像一个加强版的Memcached,那么何时使用Memcached,何时使用Redis呢?如果简单地比较Redis与Memcached的区别,大多数都会得到以下观点: 1Redis不仅仅支持简单的k/v类型的数据,同时还提供list,set,zset,hash等数据结构的存储。 2Redis支持数据的备份,即master-slave模式的数据备份。 3Redis支持数据的持久化,可以将内存中的数据保持在磁盘中,重启的时候可以再次加载进行使用。 抛开这些,可以深入到Redis内部构造去观察更加本质的区别,理解Redis的设计。 在Redis中,并不是所有的数据都一直存储在内存中的。 这是和Memcached相比一个最大的区别。 Redis只会缓存所有的 key的信息,如果Redis发现内存的使用量超过了某一个阀值,将触发swap的操作,Redis根据“swappability = age*log(size_in_memory)”计 算出哪些key对应的value需要swap到磁盘。 然后再将这些key对应的value持久化到磁盘中,同时在内存中清除。 这种特性使得Redis可以 保持超过其机器本身内存大小的数据。 当然,机器本身的内存必须要能够保持所有的key,毕竟这些数据是不会进行swap操作的。 同时由于Redis将内存 中的数据swap到磁盘中的时候,提供服务的主线程和进行swap操作的子线程会共享这部分内存,所以如果更新需要swap的数据,Redis将阻塞这个 操作,直到子线程完成swap操作后才可以进行修改。 使用Redis特有内存模型前后的情况对比: VM off: 300k keys, 4096 bytes values: 1.3G used VM on:300k keys, 4096 bytes values: 73M used VM off: 1 million keys, 256 bytes values: 430.12M used VM on:1 million keys, 256 bytes values: 160.09M used VM on:1 million keys, values as large as you want, still: 160.09M used当 从Redis中读取数据的时候,如果读取的key对应的value不在内存中,那么Redis就需要从swap文件中加载相应数据,然后再返回给请求方。 这里就存在一个I/O线程池的问题。 在默认的情况下,Redis会出现阻塞,即完成所有的swap文件加载后才会相应。 这种策略在客户端的数量较小,进行 批量操作的时候比较合适。 但是如果将Redis应用在一个大型的网站应用程序中,这显然是无法满足大并发的情况的。 所以Redis运行我们设置I/O线程 池的大小,对需要从swap文件中加载相应数据的读取请求进行并发操作,减少阻塞的时间。 如果希望在海量数据的环境中使用好Redis,我相信理解Redis的内存设计和阻塞的情况是不可缺少的。
REDIS学习查看redis状态,以及rdb和aof两种持久化方案的区别
命令:redis-cli info //查看redis服务器状态的rdb : redis database 默认开启的,是将数据从内存备份到硬盘中。 aof:append only f 需要自己根据需要开启,是将执行命令存储在一个文件中。 建议看一下apeit-程序猿IT的文章《redis数据持久化》,讲的简单明了。
发表评论