本来是基于scrapy-redis进行讲解的,需要拓展一下redis; 包含用法,设计,高并发,阻塞等; 要应用到爬虫开发中,这些基础理论我觉得还是有必要了解一下;??
所以,新开一栏! 把redis这个环节系统补上,再转回去scrapy-redis才好深入;
Redis是一种内存数据库,以其快速的性能、丰富的功能和对多种编程语言的支持而闻名。它提供了多种数据结构、持久化、简单易用、可靠性高和分布式能力。
首先,Redis的速度非常快。它可以处理高达10万次每秒的读写操作,这使得它具有出色的性能。这主要得益于Redis将数据存储在内存中,而内存操作速度非常快。此外,Redis是用C语言实现的,这也有助于提供出色的性能。它采用单线程的线程模型,这保证了操作的原子性,避免了并发问题。
除了速度快之外,Redis还具有持久化功能。它将所有的数据保存在内存中,并异步地将数据更新到磁盘中,以保证数据的持久性。这意味着即使在发生系统故障或重启时,数据也不会丢失。
Redis提供了多种数据结构,它基于键值对进行存储。其中,值可以是字符串、二进制对象、位图、哈希表、链表、集合和有序集合等。这些不同的数据结构可以适应不同的应用场景,例如缓存、计数器、分布式锁等。
另一个值得注意的特点是Redis支持多种编程语言。它提供了丰富的API,可以与多种编程语言进行交互,如Java、Python、PHP等。这使得开发者可以方便地使用Redis来构建各种应用系统。
Redis还具备丰富的功能。它支持发布订阅模式,可以实现消息的广播和订阅机制。通过使用Lua脚本,开发者可以在Redis中执行复杂的操作和业务逻辑。另外,Redis还支持事务和管道操作,可以批量执行多个命令,提高操作效率。
Redis的简单易用也是其优点之一。它提供了一套简洁而直观的命令集,如get、set、del等。通过这些基本命令,可以轻松地对Redis中的数据进行读取、写入和删除操作。
另外,Redis提供了主从复制功能,可以实现数据的备份和故障恢复。它还支持高可用性和分布式部署,可以构建具有弹性和扩展性的系统。
在使用Redis时,了解其API的使用和理解非常重要。Redis提供了通用的命令集,如keys、dbsize、exists、del、expire、type等。通过这些命令,可以操作和管理Redis中的键和值,例如查看键的数量、判断键是否存在、设置键的过期时间、删除键等。
需要注意的是,Redis采用单线程架构,虽然单线程模型非常快速,但也意味着在处理长时间的命令(如keys、flushall、mutil等)时会阻塞其他命令的执行,因此在实际使用中要避免使用这些长时间的命令,以提高整体性能。
此外,了解Redis的内部数据结构和编码方式也很重要。对外,Redis使用一种数据结构表示数据类型,如字符串、哈希表、列表、集合、有序集合和无类型。而在内部,Redis使用了不同的编码方式,如原始编码、整型编码、压缩列表、链接列表、哈希映射和整数集合等。了解这些内部实现细节可以更好地理解Redis的工作原理和优化使用。
字符串类型是Redis中常用的数据类型之一。它可以用于存储字符串、JSON等数据,但要注意value的最大大小不超过512M。字符串类型在缓存、计数器和分布式锁等场景中非常有用。下面介绍字符串类型的基本命令以及一些拓展命令,并结合案例进行讲解。
其中,get命令用于获取指定键的值,set命令用于设置键的值,del命令用于删除指定键。例如,我们可以使用以下命令来设置和获取键"haha"的值:
127.0.0.1:6379> set haha 1
OK
127.0.0.1:6379> get haha
"1"
这些命令常用于统计数据和缓存sql语句等场景。
127.0.0.1:6379> incr haha
(integer) 2
127.0.0.1:6379> get haha
"2"
可以设置键的值,不管键是否已存在;
让我们看一个示例:
127.0.0.1:6379> set foo bar
OK
127.0.0.1:6379> setnx foo baz
(integer) 0
127.0.0.1:6379> set foo baz xx
OK
在上面的示例中,首先使用set命令将键"foo"的值设置为"bar",然后使用setnx命令在键"foo"不存在时将其值设置为"baz",但因为键已存在,所以返回结果为0;最后使用set命令将键"foo"的值由"bar"更新为"baz"。
这些批量操作可以节省时间开销,提高效率。
127.0.0.1:6379> mset foo1 bar1 foo2 bar2 foo3 bar3
OK
127.0.0.1:6379> mget foo1 foo2 foo3
1) "bar1"
2) "bar2"
3) "bar3"
在上面的示例中,我们使用mset命令一次性设置了三个键值对,然后使用mget命令一次性获取了这三个键的值。
127.0.0.1:6379> getset foo baz
"bar"
127.0.0.1:6379> append foo "123"
(integer) 6
127.0.0.1:6379> strlen foo
(integer) 6
在上面的示例中,首先使用getset命令获取键"foo"的旧值"bar"并设置新值"baz",然后使用append命令将"123"追加到键"foo"的值之后,最后使用strlen命令获取键"foo"的值的长度为6。
首先,incrbyfloat命令可用于将存储为浮点数的键的值与给定的浮点数相加。如果键的值不是浮点数,Redis会将其转换为0并执行加法操作。下面是一个示例:
127.0.0.1:6379> incr fudian
(integer) 1
127.0.0.1:6379> incrbyfloat fudian 1.85
"2.85000000000000009"
在上面的示例中,我们首先使用incr命令将键"fudian"的值自增1,然后使用incrbyfloat命令将键"fudian"的值与给定的1.85相加,得到新的值"2.85000000000000009"。注意,Redis中的浮点数实际上都以字符串形式存储。
接下来,我们来了解getrange和setrange命令。
getrange命令可以返回键的值中指定位置范围内的子字符串。它需要指定起始位置和结束位置的索引。
127.0.0.1:6379> getrange ba 0 3
",daw"
在上面的示例中,我们使用getrange命令获取键"ba"的值中从索引0到3的子字符串,结果是",daw"。
setrange命令用于替换键的值中指定索引范围内的字符或子字符串。它需要指定起始位置索引和替换的新字符串。
127.0.0.1:6379> setrange ba 3 a
(integer) 9
127.0.0.1:6379> get ba
",daaoerzi"
在上面的示例中,我们使用setrange命令将键"ba"的值中索引为3的字符替换为"a",最终值变为",daaoerzi"。需要注意的是,setrange会自动扩展字符串长度以容纳替换的内容。