redis 详解系列之一(基础知识)

2019-08-11  本文已影响0人  落羽归尘

本文内容

redis概述

        redis是一种键值对的nosql数据库,值可以支持字符串(string),哈希(hash),列表(list),集合(set),有序集合(zset)等数据结构。redis是将数据存放到内存中,因此读写速度很快,另外还能将内存中数据持久化到硬盘,保证数据不会丢失。除了redis支持的5中数据结构,还有许多额外的额功能,比如键过期功能实现缓存,发布订阅功能实现消息系统等。
        redis之所以速度快,官方数据是读写性能10万/秒,原因在于:1,redis是用C语言实现的;2,redis是单线程架构,减少了多线程竞争的开销,避免线程切换和锁机制;3,非阻塞IO,redis使用epoll多路复用技术,使得不会在网络IO上浪费太多时间。
        redis对外有五种数据结构(string,hash,list,set,zset),每种数据结构都有两种以上的内部编码实现,可以通过命令object encoding查看

127.0.0.1:6379> object encoding h
"embstr"

这样的设计有两个好处,1,改进内部编码时,对外部无影响;2,不同的编码在不同的场景下有不同的优势。

redis使用场景

        1,redis可用于缓存,大部分的大型网站都需要缓存层,为了保护存储层,使用缓存能加快访问速度,降低后端服务器数据源的压力,2,可用于排行榜系统,可根据list和zset数据结构,方便的构建排行榜系统,3,可应用于计数器应用,4,订阅发布,消息系统

redis单线程

        redis使用的是单线程架构和IO多路复用实现高性能的内存数据库,每次客户端调用命令都是经过三个过程:发送命令、执行命令、返回结果。由于单线程架构,一条命令达到服务端的时候不会立刻执行,所有的命令都会进入到一个队列中排队执行,不会有两个命令同时执行的情况。但是注意,单线程情况下,如果一个命令执行时间过长,会对其他命令造成阻塞,对整个redis服务造成影响。

redis常用命令

全局命令

        RedisDesktopManager是一种redis的可视化工具,使用非常简单。

127.0.0.1:6379> keys *
 1) "a,1"
 2) "a:2"
 3) "aa"
 4) "z"
 5) "a:1"
 6) "b"
 7) "z1"
 8) "c"
 9) "s1"
10) "s"
11) "h"
127.0.0.1:6379> dbsize
(integer) 11
127.0.0.1:6379> exists a
(integer) 0
127.0.0.1:6379> exists b
(integer) 1
127.0.0.1:6379> exists d
(integer) 1
127.0.0.1:6379> del d
(integer) 1
127.0.0.1:6379> exists d
(integer) 0
127.0.0.1:6379> del a b c
(integer) 3
127.0.0.1:6379> expire c 10
(integer) 1
127.0.0.1:6379> exists c
(integer) 0
127.0.0.1:6379> type h
string

字符串(string)

        字符串是redis数据结构中最基础的,其他数据结构都是在其之上构建的。字符串类型的值,可以是字符串(string,json,xml等),数字(int,float),二进制等,但是请注意,最大不能超过512MB

常用命令
127.0.0.1:6379> set hello world
OK

选项:
-ex 设置秒级别的过期时间
-px 设置毫秒级别的过期时间
-nx:键必须不存在,才可以设置成功,用于添加。
-xx:与nx相反,键必须存在,才可以设置成功,用于更新。
除set命令,还有setnx,setex,作用和选项-ex,-nx作用一样。

setex key seconds value
setnx key value
127.0.0.1:6379> set a test
OK
127.0.0.1:6379> setnx a test   # 由于a键已经存在,所以设置失败
(integer) 0
127.0.0.1:6379> set a test1 XX # 由于a键已经存在,所以更新成功
OK
127.0.0.1:6379> get a
"test1"
127.0.0.1:6379> get a1
(nil)
127.0.0.1:6379> mset k1 v1 k2 v2
OK
127.0.0.1:6379> mget k1 k2
1) "v1"
2) "v2"

批量操作能提高效率,执行时间较短,但是使用批量操作时,要注意数量,防止过多造成网络阻塞,或者redis阻塞。

127.0.0.1:6379> incr key1
(integer) 1
127.0.0.1:6379> incr key1
(integer) 2

字符串类型的内部编码有三种,int:8字节的长整形,embstr:小于等于39字节的字符串,raw:大于39字节的字符串。
redis根据具体场景选择不同的编码。

使用场景

哈希(hash)

        hash是形如键值对的类型,比如python中的字典。

常用命令
127.0.0.1:6379> hset user:1 name z
(integer) 1

同样,也有hsetnx命令,作用同string的setnx

127.0.0.1:6379> hget user:1 name
"z"
127.0.0.1:6379> hkeys user:1
1) "name"
127.0.0.1:6379> hvals user:1
1) "z"
127.0.0.1:6379> hgetall user:1
时间复杂度O(n)
1) "name"
2) "z"

同样,hash也有好几种内部编码,根据不同场景选择合适的。

使用场景

列表(list)

        list可以用于存储多个有序的字符串,一个list最多可以存储2**32-1个元素。可以充当队列和栈。开发中有很多使用场景。

常用命令
127.0.0.1:6379> rpush l a s 1
(integer) 3
127.0.0.1:6379> lpush l k n
(integer) 5
127.0.0.1:6379> linsert l before k k1
(integer) 6

127.0.0.1:6379> lrange l 0 -1
1) "n"
2) "k1"
3) "k"
4) "a"
5) "s"
6) "1"
127.0.0.1:6379> lpop l
"n"
127.0.0.1:6379> rpop l
"1"
127.0.0.1:6379> lrem l 1 k
(integer) 1
127.0.0.1:6379> lrange l 0 -1
1) "k1"
2) "a"
3) "s"
127.0.0.1:6379> ltrim l 0 1
OK
127.0.0.1:6379> lrange l 0 -1
1) "k1"
2) "a"
127.0.0.1:6379> lset l 0 k2
OK
127.0.0.1:6379> lrange l 0 -1
1) "k2"
2) "a"

阻塞操作:
blpop key [key ...] timeout #list空时,timeout时间内返回,当timeout=0,无限阻塞下去. 时间复杂度O(1)
brpop key [key ...] timeout
如在一个客户端执行
127.0.0.1:6379> brpop list:test 3
另一个客户端做插入动作,观察第一个客户端情况。

使用场景

集合(set)

        set也是可以用于存储多个有序的字符串,但是里面的元素是无序的,而且没有重复的。一个set里最多有2**32-1个元素,set除了增删改查,还有交集并集的操作。

常用命令
127.0.0.1:6379> sadd s a b c 1 2 3
(integer) 6
127.0.0.1:6379> srem s b
(integer) 1
127.0.0.1:6379> scard s
(integer) 5
127.0.0.1:6379> sismember s a
(integer) 1
127.0.0.1:6379> srandmember s 3
1) "c"
2) "3"
3) "a"
127.0.0.1:6379> spop s
"1"
127.0.0.1:6379> smembers s
1) "c"
2) "2"
3) "3"
4) "a"

127.0.0.1:6379> smembers s
1) "c"
2) "2"
3) "3"
4) "a"
127.0.0.1:6379> sadd s1 1 2 3 a b c
(integer) 4
127.0.0.1:6379> sinter s s1
1) "c"
2) "2"
3) "3"
4) "a"
127.0.0.1:6379> sunion s s1
1) "6"
2) "1"
3) "c"
4) "5"
5) "2"
6) "3"
7) "b"
8) "a"
127.0.0.1:6379> sdiff s s1
(empty list or set)
127.0.0.1:6379> sdiff s1 s
1) "6"
2) "5"
3) "1"
4) "b"
127.0.0.1:6379> sinterstore d1 s s1
(integer) 4
127.0.0.1:6379> smembers d1
1) "2"
2) "3"
3) "c"
4) "a"
使用场景

有序集合(zset)

        有序集合保留了set的无重复特性,但是比之多一个特点是有序,给每个元素设置一个score作为排行依据,score的值可以重复。

常用命令
127.0.0.1:6379> zadd zs 2 a 20 b 200 c
(integer) 3
127.0.0.1:6379> zadd zs 2 a 20 b 200 c
(integer) 3
127.0.0.1:6379> zcard zs
(integer) 3
127.0.0.1:6379> zscore zs b
"20"
127.0.0.1:6379> zrank zs b
(integer) 1
127.0.0.1:6379> zincrby zs 30 b
"50"
127.0.0.1:6379> zrange zs 1 3
1) "b"
2) "c"

参考书

《redis开发与运维(付磊)》

上一篇 下一篇

猜你喜欢

热点阅读