Redis基本介绍以及常用命令操作

1、Redis简介

        关系型数据库是基于关系表的数据库,最终会将数据持久化到磁盘上,而nosql数据 库是基于特殊的结构,并将数据存储到内存的数据库。从性能上而言,nosql数据库 要优于关系型数据库,从安全性上而言关系型数据库要优于nosql数据库,所以在实 际开发中一个项目中nosql和关系型数据库会一起使用,达到性能和安全性的双保证。

2、redis在Linux上的安装

1)安装redis编译的c环境,yum install gcc-c++

2)将redis-2.6.16.tar.gz上传到Linux系统中

3)解压到/usr/local下 tar -xvf redis-2.6.16.tar.gz -C /usr/local

4)进入redis-2.6.16目录 使用make命令编译redis

5)在redis-2.6.16目录中 使用make PREFIX=/usr/local/redis install命令安装 redis到/usr/local/redis中

6)拷贝redis-2.6.16中的redis.conf到安装目录redis中 7)启动redis 在bin下执行命令redis-server redis.conf 8)如需远程连接redis,需配置redis端口6379在linux防火墙中开发 /sbin/iptables -I INPUT -p tcp --dport 6379 -j ACCEPT /etc/rc.d/init.d/iptables save

                              

 

启动后看到如上欢迎页面,但此窗口不能关闭,窗口关闭就认为redis也关闭了(类 似Tomcat通过bin下的startup.bat的方式) 解决方案:可以通过修改配置文件 配置redis后台启动,即服务器启动了但不会 穿件控制台窗口 将redis.conf文件中的daemonize从false修改成true表示后台启动 使用命令查看6379端口是否启动ps -ef | grep redis

                             

3、Redis常用命令

redis是一种高级的key-value的存储系统 其中的key是字符串类型,尽可能满足如下几点:

1)key不要太长,最好不要操作1024个字节,这不仅会消耗内存还会降低查找 效率

2)key不要太短,如果太短会降低key的可读性 3)在项目中,key最好有一个统一的命名规范(根据企业的需求) 其中value 支持五种数据类型:

1)字符串型 string

    应用场景计数器、浏览量,关注数等等,string更适合存储字符串

2)字符串列表 lists

    应用场景:队列、栈、可用作消息队列,在两边均可添加或者删除元素,查找的话就比一般链表要快

3)字符串集合 sets

   应用场景:对于一些交集,共同好友、共同关注比较常用

4)有序字符串集合 sorted sets

   应用场景:在一些排序场景比较常用,例如员工按薪水排序,文章按浏览量排序等

5)哈希类型 hashs

  应用场景:存取对象比较实用,对象一般会有许多的属性,通过操作hash的key值,找到相应的key-value属性,就是单一对象属性

我们对Redis的学习,主要是对数据的存储,下面将来学习各种Redis的数据类型的 存储操作:

 

三种特殊类型

 1:geospatial 地理位置

     朋友的定位、附近的人、打车距离计算,这个功能可以推算地理位置的信息,两地之间的距离,方圆几里的人。

2:HyperLogLog j(基数统计的算法)

优点:占用内存比较小

一个集合内不重复的元素 = 基数

应用场景:uv:一个网站的浏览量(当一个人访问一个网站,不管一天内访问多少次都只算是一次)

传统方法:通过set保存用户的id,一个set集合中会过滤掉重复的id;在并发量大的时候可能会有数据缺失,如果保存大量的id,就会比较麻烦。因为我们的目的是为了计数,而不是保存用户id;

redis 127.0.0.1:6379> PFADD mykey a b c d e f g h i j
(integer) 1
redis 127.0.0.1:6379> PFCOUNT mykey
(integer) 10

3:Bitmaps(位存储)

统计用户信息:活跃、不活跃;登录、未登录;打卡、未打卡;就是具有两种状态的都可以运用bitmaps;

bitmaps位图是二进制操作,就是运用0和1来操作;

具体场景举例:周一到周五的打卡,统计打卡数;

统计打卡总数

bitcount sign

 

3.1存储字符串string

字符串类型是Redis中最为基础的数据存储类型,它在Redis中是二进制安全的,这 便意味着该类型可以接受任何格式的数据,如JPEG图像数据或Json对象描述信息等。 在Redis中字符串类型的Value最多可以容纳的数据长度是512M

                                                  

 

1)set key value:设定key持有指定的字符串value,如果该key存在则进行覆盖 操作。总是返回”OK”

2)get key:获取key的value。如果与该key关联的value不是String类型,redis 将返回错误信息,因为get命令只能用于获取String value;如果该key不存在,返 回null。

           

                                 

 

3)getset key value:先获取该key的值,然后在设置该key的值。

                               

4)incr key:将指定的key的value原子性的递增1.如果该key不存在,其初始值 为0,在incr之后其值为1。如果value的值不能转成整型,如hello,该操作将执 行失败并返回相应的错误信息。

5)decr key:将指定的key的value原子性的递减1.如果该key不存在,其初始值 为0,在incr之后其值为-1。如果value的值不能转成整型,如hello,该操作将执 行失败并返回相应的错误信息。

                                 

 

6)incrby key increment:将指定的key的value原子性增加increment,如果该 key不存在,器初始值为0,在incrby之后,该值为increment。如果该值不能转成 整型,如hello则失败并返回错误信息

7)decrby key decrement:将指定的key的value原子性减少decrement,如果 该key不存在,器初始值为0,在decrby之后,该值为decrement。如果该值不能 转成整型,如hello则失败并返回错误信息

                                   

 

 


8)append key value:如果该key存在,则在原有的value后追加该值;如果该 key 不存在,则重新创建一个key/valu
e

                                     

 

3.2存储lists类型

在Redis中,List类型是按照插入顺序排序的字符串链表。和数据结构中的普通链表 一样,我们可以在其头部(left)和尾部(right)添加新的元素。在插入时,如果该键并不 存在,Redis将为该键创建一个新的链表。与此相反,如果链表中所有的元素均被移 除,那么该键也将会被从数据库中删除。List中可以包含的最大元素数量是 4294967295。

 从元素插入和删除的效率视角来看,如果我们是在链表的两头插入或删除元素,这将 会是非常高效的操作,即使链表中已经存储了百万条记录,该操作也可以在常量时间 内完成。然而需要说明的是,如果元素插入或删除操作是作用于链表中间,那将会是 非常低效的。相信对于有良好数据结构基础的开发者而言,这一点并不难理解。

                                                   

 

1)lpush key value1 value2...:在指定的key所关联的list的头部插入所有的 values,如果该key不存在,该命令在插入的之前创建一个与该key关联的空链 表,之后再向该链表的头部插入数据。插入成功,返回元素的个数。

2)rpush key value1、value2…:在该list的尾部添加元素

3)lrange key start end:获取链表中从start到end的元素的值,start、end可 为负数,若为-1则表示链表尾部的元素,-2则表示倒数第二个,依次类推… 

4)lpushx key value:仅当参数中指定的key存在时(如果与key管理的list中没 有值时,则该key是不存在的)在指定的key所关联的list的头部插入value。

5)rpushx key value:在该list的尾部添加元素

6)lpop key:返回并弹出指定的key关联的链表中的第一个元素,即头部元素。

7)rpop key:从尾部弹出元素。

 


8)rpoplpush resource destination:将链表中的尾部元素弹出并添加到头部

9)llen key:返回指定的key关联的链表中的元素的数量。

10)lset key index value:设置链表中的index的脚标的元素值,0代表链表的头元 素,-1代表链表的尾元素。

11)lrem key count value:删除count个值为value的元素,如果count大于0,从头向尾遍历并删除count个值为value的元素,如果count小于0,则从尾向头遍历并删除。如果count等于0,则删除链表中所有等于value的元素。

12)linsert key before|after pivot value:在pivot元素前或者后插入value这个 元素。

3.3 存储sets类型

在Redis中,我们可以将Set类型看作为没有排序的字符集合,和List类型一样,我 们也可以在该类型的数据值上执行添加、删除或判断某一元素是否存在等操作。需要 说明的是,这些操作的时间是常量时间。Set可包含的最大元素数是4294967295。

和List类型不同的是,Set集合中不允许出现重复的元素。和List类型相比,Set类 型在功能上还存在着一个非常重要的特性,即在服务器端完成多个Sets之间的聚合计 算操作,如unions、intersections和differences。由于这些操作均在服务端完成, 因此效率极高,而且也节省了大量的网络IO开销

 

1)sadd key value1、value2…:向set中添加数据,如果该key的值已有则不会 重复添加 l

2)smembers key:获取set中所有的成员 l

3)scard key:获取set中成员的数量

4)sismember key member:判断参数中指定的成员是否在该set中,1表示存 在,0表示不存在或者该key本身就不存在

5)srem key member1、member2…:删除set中指定的成员

6)srandmember key:随机返回set中的一个成员

7)sdiff sdiff key1 key2:返回key1与key2中相差的成员,而且与key的顺序有 关。即返回差集。

8)sdiffstore destination key1 key2:将key1、key2相差的成员存储在   destination上

9)sinter key[key1,key2…]:返回交集。

10)sinterstore destination key1 key2:将返回的交集存储在destination上

11)sunion key1、key2:返回并集。

12)sunionstore destination key1 key2:将返回的并集存储在destination上

3.4、存储sortedset

Sorted-Sets和Sets类型极为相似,它们都是字符串的集合,都不允许重复的成员出 现在一个Set中。它们之间的主要差别是Sorted-Sets中的每一个成员都会有一个分 数(score)与之关联,Redis正是通过分数来为集合中的成员进行从小到大的排序。然 而需要额外指出的是,尽管Sorted-Sets中的成员必须是唯一的,但是分数(score) 却是可以重复的。

在Sorted-Set中添加、删除或更新一个成员都是非常快速的操作,其时间复杂度为 集合中成员数量的对数。由于Sorted-Sets中的成员在集合中的位置是有序的,因此, 即便是访问位于集合中部的成员也仍然是非常高效的。事实上,Redis所具有的这一 特征在很多其它类型的数据库中是很难实现的,换句话说,在该点上要想达到和Redis 同样的高效,在其它数据库中进行建模是非常困难的。

例如:游戏排名、微博热点话题等使用场景。

                                                        

 

1)zadd key score member score2 member2 … :将所有成员以及该成员的 分数存放到sorted-set中

2)zcard key:获取集合中的成员数量

l3)zcount key min max:获取分数在[min,max]之间的成员 l

zincrby key increment member:设置指定成员的增加的分数。 l

zrange key start end [withscores]:获取集合中脚标为start-end的成员,[withscores]参数表明返回的成员包含其分数。 zrangebyscore key min max [withscores] [limit offset count]:返回分数在[min,max]的成员并按照分数从低到高排序。[withscores]:显示分数;[limit offset count]:offset,表明从脚标为offset的元素开始并返回count个成员。

zrank key member:返回成员在集合中的位置。

zrem key member[member…]:移除集合中指定的成员,可以指定多个成员。 lzscore key member:返回指定成员的分数

 

3.5、存储hash

Redis中的Hashes类型可以看成具有String Key和String Value的map容器。所 以该类型非常适合于存储值对象的信息。如Username、Password和Age等。如果 Hash中包含很少的字段,那么该类型的数据也将仅占用很少的磁盘空间。每一个Hash 可以存储4294967295个键值对。

                                                           

 

1)hset key field value:为指定的key设定field/value对(键值对)。

2)hgetall key:获取key中的所有filed-vaule

3)hget key field:返回指定的key中的field的值

4)hmset key fields:设置key中的多个filed/value

5)hmget key fileds:获取key中的多个filed的值

6)hexists key field:判断指定的key中的filed是否存在

7)hlen key:获取key所包含的field的数量

8)hincrby key field increment:设置key中filed的值增加increment,如:age 增加20

 

4、事务

4.1 redis事务的基本概念

Redis事务的本质:一组命令的集合;在事务执行过程中,会按照顺序来执行;

一次性、顺序性、排他性;执行一系列的命令

例如

----队列  set set set  执行 ----

redis事务没有隔离级别的概念

   所有命令没有直接被执行,只有发起命令的时候才会被执行,也就没有mysql数据库里面的脏读等等;

redis单条命令是保证原子性的,但是事务不保证原子性;

redis事务

    1.开启事务(multi)

    2.命令入队(比如set k1 v1等命令一个个命令入队,但是没有执行)

    3.执行事务(exec,执行命令,会将队里的命令按顺序来一个个执行)

注:每次执行完一组事务之后,这组事务就没用了,下次需要重新开启事务multi

放弃事务

discard

 

编译型异常(命令行出错、代码有问题!),那么事务中所有的命令都不会被执行;

 

运行时异常

 

4.2 监控!watch

悲观锁:

       1.总之就是很悲观,认为什么时候都会出现问题,所以无论做什么都会加锁,因此性能也相对降低了;

乐观锁:

     1.总之呢就是很乐观,认为什么时候都不会出现问题,所以做什么都不会加锁;只不过更新数据的时候回去判断一下,看下是否有人改变过数据;

      2.获取version

      3.更新的时候比较version

 

redis检测测试

 测试redis的修改值,使用watch可以当作redis的乐观锁来看待

如果失败,先解锁

unwatch money  --解锁

watch money --加锁

乐观锁应用场景:乐观锁实现秒杀系统

  我们知道大多数是基于数据版本(version)的记录机制实现的。即为数据增加一个版本标识,在基于数据库表的版本解决方案中,一般是通过为数据库表增加一个”version”字段来实现读取出数据时,将此版本号一同读出,之后更新时,对此版本号加1。此时,将提交数据的版本号与数据库表对应记录的当前版本号进行比对,如果提交的数据版本号大于数据库当前版本号,则予以更新,否则认为是过期数据。redis中可以使用watch命令会监视给定的key,当exec时候如果监视的key从调用watch后发生过变化,则整个事务会失败。也可以调用watch多次监视多个key。这样就可以对指定的key加乐观锁了。注意watch的key是对整个连接有效的,事务也一样。如果连接断开,监视和事务都会被自动清除。当然了exec,discard,unwatch命令都会清除连接中的所有监视。

  Redis中的事务(transaction)是一组命令的集合。事务同命令一样都是Redis最小的执行单位,一个事务中的命令要么都执行,要么都不执行。Redis事务的实现需要用到 MULTI 和 EXEC 两个命令,事务开始的时候先向Redis服务器发送 MULTI 命令,然后依次发送需要在本次事务中处理的命令,最后再发送 EXEC 命令表示事务命令结束。Redis的事务是下面4个命令来实现 :

1).multi,开启Redis的事务,置客户端为事务态。

2).exec,提交事务,执行从multi到此命令前的命令队列,置客户端为非事务态。

3).discard,取消事务,置客户端为非事务态。

4).watch,监视键值对,作用时如果事务提交exec时发现监视的监视对发生变化,事务将被取消。

 

5、redis配置文件

5.1 网络

5.2 通用配置

 

5.3 redis快照

5.4 SECURITY 安全

5.5 限制CLIENTS

5.6 append only模式 aof配置

 

6、redis持久化

redis是一个内存数据库,数据保存在内存当中;因为内存的数据变化是很快的,也很容易发生丢失。所以我们需要对redis进行持久化操作,redis的持久化分为两种,分别是rdbaof;

持久化模式说明优点缺点
rdb模式定期将redis当前内存数据快照备份到硬盘redis重启时恢复速度快由于备份不宜频繁,会导致系统异常宕机时,redis大量数据丢失
aof模式将redis执行的命令每隔1s批量同步到文件中机器异常宕机时,最多丢失1s数据由于保存的是命令,会导致保存很多赘余数据,文件过大(这时候恢复起来相对rdb会慢很多)

 

6.1 rdb持久化

什么是rdb呢,rdb其实就是把数据以快照的形式保存在磁盘上;什么是快照,可以理解位为把当前时刻的数据拍成一张照片保存下来;
RDB持久化是指在指定的时间间隔内将内存中的数据集快照写入磁盘。也是默认的持久化方式,这种方式是就是将内存中数据以快照的方式写入到二进制文件中,默认的文件名为dump.rdb。

在我们安装了redis之后,所有的配置都是在redis.conf文件中,里面保存了RDB和AOF两种持久化机制的各种配置

既然RDB机制是通过把某个时刻的所有数据生成一个快照来保存,那么就应该有一种触发机制,是实现这个过程。对于RDB来说,提供了三种机制:save、bgsave、自动化。我们分别来看一下

6.1.1 RDB持久化

1、save触发方式

该命令会阻塞当前Redis服务器,执行save命令期间,Redis不能处理其他命令,直到RDB过程完成为止。具体流程如下:

 

                              

执行完成时候如果存在老的RDB文件,就把新的替代掉旧的。我们的客户端可能都是几万或者是几十万,这种方式显然不可取。

 

2、bgsave触发方式

执行该命令时,Redis会在后台异步进行快照操作,快照同时还可以响应客户端请求。具体流程如下

 

                              

 

具体操作是Redis进程执行fork操作创建子进程,RDB持久化过程由子进程负责,完成后自动结束。阻塞只发生在fork阶段,一般时间很短。基本上 Redis 内部所有的RDB操作都是采用 bgsave 命令。

 

3、自动触发

自动触发是由我们的配置文件来完成的。在redis.conf配置文件中,上面的配置文件有提到过。

                                                                                    save与bgsave的区别

命令savebgsave
IO类型同步异步
阻塞是(阻塞发生在fork)
复杂度O(n)O(n)
优点不会消耗额外内存不阻塞客户端命令
缺点阻塞客户端命令需要fork,消耗内存

4、RDB的优势和劣势

    ①、优势

           (1)RDB文件紧凑、全量备份,非常适合用于进行备份和灾难恢复。

           (2)生成RDB文件的时候,redis主进程会fork()一个子进程来处理所有保存工作,主进程不需要进行任何磁盘IO的操作.

             (3)   RDB在恢复大数据集时速度比AOF的恢复速度要快

   ②、劣势

            (1)RDB快照时一次全量备份,存储的是内存数据的二进制序列化形式,存储上非常紧凑。当进行快照持久化时,会开            启一个子进程专门负责快照持久化,子进程会拥有父进程的内存数据,父进程修改内存子进程不会反应出来,所以在快照            持久化期间修改的数据不会被保存,可能丢失数据。

简单来说

5、RDB触发规则

 

 

6、如何恢复RDB文件的数据

 

6.1.2 AOF(append only file)持久化 

我们知道,利用RDB在进行全量备份的时候,总是很耗时间的,有时候我们可以用一种更加高效的持久化方式(aof)进行操作。

什么是aof的工作机制呢!简单来讲,redis会将每一个收到的写命令都通过write函数追加到文件中。通俗来讲就是日志记录。

aof的开启

    1、aof持久化原理

 

每当有一个写命令过来时,就直接保存在我们的AOF文件中。

 

 

    2、文件重写原理

当利用aof进行持久化的时候,也会遇到一个问题,就是持久化文件会变得越来越大。为了压缩aof的持久化文件。redis提供了bgrewriteaof命令。将内存中的数据以命令的方式保存到临时文件中,同时会fork出一条新进程来将文件重写。

重写aof文件的操作,并没有读取旧的aof文件,而是将整个内存中的数据库内容用命令的方式重写了一个新的aof文件,这点和快照有点类似。

 

    3、AOF也有三种触发机制

(1)每修改同步always:同步持久化 每次发生数据变更会被立即记录到磁盘 性能较差但数据完整性比较好

(2)每秒同步everysec:异步操作,每秒记录 如果一秒内宕机,有数据丢失

(3)不同no:从不同步

      4、优点

         (1)AOF可以更好的保护数据不丢失,一般AOF会每隔1秒,通过一个后台线程执行一次fsync操作,最多丢失1秒钟的数            据。

         (2)AOF日志文件没有任何磁盘寻址的开销,写入性能非常高,文件不容易破损。

         (3)AOF日志文件即使过大的时候,出现后台重写操作,也不会影响客户端的读写。

         (4)AOF日志文件的命令通过非常可读的方式进行记录,这个特性非常适合做灾难性的误删除的紧急恢复。比如某人不            小 心用flushall命令清空了所有数据,只要这个时候后台rewrite还没有发生,那么就可以立即拷贝AOF文件,将最后一条              flushall命令给删了,然后再将该AOF文件放回去,就可以通过恢复机制,自动恢复所有数据

    5、缺点

         (1)对于同一份数据来说,AOF日志文件通常比RDB数据快照文件更大

         (2)AOF开启后,支持的写QPS会比RDB支持的写QPS低,因为AOF一般会配置成每秒fsync一次日志文件,当然,每秒        一次fsync,性能也还是很高的

         (3)以前AOF发生过bug,就是通过AOF记录的日志,进行数据恢复的时候,没有恢复一模一样的数据出来。

 

 

 

 

 

 

 

 

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值