.Net转Java自学之路—Redis篇

Redis:

  关系型数据库(SQL):MySQL、Oracle

    特点:数据与数据之间,表与字段之间,表与表之间是存在关系的

    优点:
      1、数据之间有关系,进行数据的增删改查时非常方便。
      2、关系型数据库,有事物操作。保证数据的完整性。

    缺点:
      1、因为数据和数据之间有关系,是由底层大量算法保证的。大量算法会拉低系统运行速度。大量算法会消耗系统资源
      2、海量数据的增删改查时,会显的无能为力。在做某些操作时,很可能会宕机(卡死)
      3、在海量数据环境下对数据表进行维护/扩展,也会变得无能为力。适合处理一般量级的数据。保证的是安全。

  非关系性数据库(NOSQL):Redis、mongoDB

    为了处理海量数据,需要将关系型数据库的关系 去掉。非关系型数据库设计之初,是为了替代关系型数据库的。

    优点:
      1、海量数据的增删改查,非常轻松。
      2、海量数据的维护/扩展,也会非常轻松。

    缺点:
      1、因为数据与数据之间没有关系,所以不能一目了然。
      2、非关系型数据库,没有关系,没有强大的事物来保证数据的完整和安全。

    适合处理海量数据,保证的是效率。不一定安全。

  NoSql数据库的四大分类:

    1、键值(Key-Value)存储数据库。

      相关产品:Tokyo Cabinet/Tyrant、Redis、Voldemort、Berkeley DB
      典型应用:内容缓存,主要用于处理大量数据的高访问负载
      数据模型:一系列的键值对。
      优势:优秀的快速查询,稳定性强。
      劣势:存储的数据缺少结构化。

    2、列存储数据库

      相关产品:Cassandra、HBase、Riak
      典型应用:分布式的文件系统。
      数据模型:以列簇式存储,将同一列数据存储在一起。
      优势:查找速度快,可扩展性强,更容易进行分布式扩展
      劣势:功能相对局限,使用极大的内存才可调配,且系统处理算法时将有数秒,甚至更长时间的不可用,导致大量处理超时。

    3、文档型数据库(淘汰)

      相关产品:CouchDB、MongoDB
      典型应用:Web应用(与Key-Value类似,Value时结构化的)
      数据模型:一系列键值对
      优势:数据结构要求不严格
      劣势:查询性能不高,而且缺乏统一的查询语法。

    4、图形(Graph)数据库:

      相关产品:Neo4J、InfoGrid、Infinite Graph
      典型应用:社交网络(关系网)
      数据模型:图结构
      优势:利用图结构相关算法。
      劣势:需要对整个图做计算才能得出结果,不容易做分布式的集群方案。局限性过强。

  Redis使用环境:
    1、可以作为关系型数据库的缓存存在。
    2、可以做任务队列。
    3、可以做大量数据运算。
    4、可以做大量数据的排行榜。  

  Linux系统 Redis 安装:

    redis是C语言开发,安装redis需要先将官网下载的源码进行编译,编译依赖gcc环境。如果没有gcc环境,需要安装gcc:yum install gcc-c++

    1、上传redis.tar.gz的安装包。并解压到当前目录:tar -zxvf redis-3xxxxx.tar.gz

    2、编译redis(编译,将.c文件编译为.o文件)
      进入解压文件夹:cd redis-3xxxxx
      执行 make
      如果没有安装gcc,编译将出现错误提示。(安装失败,必须删除文件夹,重新解压)

    3、安装:make PREFIX=/usr/local/redis install
      PREFIX指定的目录可以随意指定。
      安装完后,在/usr/local/redis/bin下有几个可执行文件:
        redis-benchmark >> 性能测试工具
        redis-check-aof >> AOF文件修复工具
        redis-check-dump >> RDB文件检查工具(快照持久化文件)
        redis-cli >> 命令行客户端
        redis-server >> redis服务器启动命令

    4、回到根目录:cd ~ 进入redis-3xx 文件中,
      Copy复制redis.conf文件到/usr/local/redis目录下(和bin同级目录中)

    注:若没有配置文件redis也可以启动,不过将启动默认配置,不方便修改端口号等信息。

  Redis启动:对应默认端口号6379

    前端启动:进入/usr/local/redis文件夹下:./bin/redis-server 启动
      启动客户端:./bin/redis-cli 或 ./bin/redis-cli -h IP地址 -p 6379
      缺点:无法部署集群。

    后端启动:修改redis.conf配置文件,将daemonize改为yes以后端模式启动
      启动时,指定配置文件:进入/usr/local/redis:cd /usr/local/redis
      启动:./bin/redis-server ./redis.conf

  Redis关闭:

    1、查询PID,kill -9 pid 杀死进程。
      相当于断电,非正常关闭,很可能会造成数据丢失。
    2、正常关闭:正常关闭,数据保存
      ./bin/redis-cli shutdown

Redis数据类型:

  redis使用的时键值对 保存数据。相当于Map 。

  key:都是字符串。key名都是自定义的。

  value:对应五种数据类型

    1、String字符串
    2、hash:数据格式类似于JSON
      例:{uname:"zs",age:"18"}
    3、list集合: 相当于Java中的LinkedList链表。添加/删除效率极高。
      例:[1,2,3,4]
    4、set:相当于Java中的HashSet
      例:['a','b','c']
    5、有序的set集合:
      例:[1000 'a',100 'b' 10 'c']

  String:

    字符串类型时Redis中最为基础、常用的数据存储类型。字符串在Redis中二进制安全的。这意味者该类型存入和获取的数据相同。在Redis中字符串类型的Value最多可以容纳的数据长度为512M。

    二进制安全和数据安全是没有关系的。

    MySQL关系型数据库,二进制不安全。因为存储的编码和取出的编码格式不一致,会造成乱码而丢失数据。

      1、频繁的编解码会浪费大量的系统性能。

      2、频繁的编解码很可能因为码表不同导致乱码。

      所以二进制不安全。

    Redis非关系型数据库,二进制安全。

      1、编解码都是在客户端完成的。没有频繁编解码,执行效率高。

      2、没有频繁编解码,不会出现乱码。

      所以二进制数据安全。

    赋值(增、改):

      set key value :设定key只有指定的字符串value
        如果该key存在则进行覆盖(修改)操作。总是返回"OK"

    取值(查):

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

    删:

      del key :删除指定key。返回值是数字类型。表示删除几条数据。

    扩展:

      getset key value:先获取该key的值,再设置该key的值。

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

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

      append key value:拼凑字符串。
        若该key存在,则在原来的value后追加该值。
        若该key不存在,则重新创建一个key,并赋值value。

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

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

    String的使用环境:主要用于保存JSON格式的字符串。

  hash:

    Redis中的Hash类型可以堪称具有String key和String value的map容器。每一个Hash可以存储4294967295个键值对。

    赋值:

      hset key field value :为指定的key设定field/value对(键值对)。相当于 增。

      hmset key field value field1 value1...:为指定的key设定多个field/value对(键值对)。

    取值:

      hget key field:获取指定的key的field值。

      hmget key field field1...:获取指定key的多个field值。

      hgetall key:获取key中的所有field-value。

    删除:

      hdel key field field1...:删除一个或多个field字段。

      del key:删除正个hash。

    扩展:

      hincrby key field increment :设置key中field的值增加increment。

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

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

      hkeys key :获取所有的字段。

      hvals key :获取所有的value。

  list:

    链表LinkList。Redis操作中,最多的操作是进行元素的增删。

    使用环境:

      1、做大数据集合的增删
      2、做任务队列

    赋值:

      lpush key values[value1 value2...]:在指定的key所关联的list头部插入所有的values。
        若该key不存在,该命令在插入的之前创建一个与该key关联的空链表,之后再向该链表的头部插入数据。插入成功,返回元素的个数。
        例:lpush list1 a b c d

      rpush key values[value1 value2...]:在该list的尾部添加元素。
        例:rpush list2 a b c d

    取值:

      lrange key start end:获取链表中从start到end的元素的值。start、end从0开始计数;也可为负数。
        若为-1 则表示链表尾部的元素;-2 则表示倒数第二个元素;以此类推...
        例:取全部元素:lrange key 0 -1

    删除:

      lpop key:返回并弹出指定的key关联的链表中的第一个元素,即头部元素。
        若该key不存在,返回nil;
        若该key存在,则返回链表的头部元素。

      rpop key:从尾部弹出元素。

    扩展:

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

      lrem key count value:删除某种元素。效率极为低下。删除count个值为value的元素。
        若count大于0,从头向尾遍历并删除count个值为value的元素。
        若count小于0,则从尾向头遍历并删除正数count个值为value的元素。
        若count等于0,则删除链表中所有等于value的元素。
        例:lrem list1 0 a 表示从左删除list1中所有的a
          lrem list1 2 a 表示从头删除list1中的2个a
          lrem list1 -2 a 表示从尾删除list1中的2个a

      lset key index value:通过索引替换元素。效率不高。设置链表中的index的角标的元素值。0代表链表的头元素,-1代表链表的尾元素。操作链表的角标不存在则抛异常。

      linsert key before/after prvot value:从索引前/后插入元素。效率不高。在pivot元素前或后插入value这个元素。

      rpoplpush resource destination:将链表中的尾部元素弹出并添加到头部。[循环操作]
        例:rpoplpush list1 list2 俩队排列
          rpoplpush list1 list1 循环队列

  set:

    set集合中不允许出现重复的元素。

    作用:在Redis操作中,涉及到俩个大数据集合的并集、交集、差集的运算。

    赋值:

      sadd key values[value1、value2...]:向set中添加数据,若该key的值已存在则不会重复添加
        例:sadd set1 a b c d

    取值:

      smembers key :获取set中所有元素。
        例:smembers set1

      sismember key member:判断参数中指定的成员是否在该set中。1 表示存在,0 表示不存在或该key本身就不存在。无论集合中有多少元素都可以极快的返回结果。
        例:sismember set1 a 判断集合set1中是否有a元素

    删除:

      srem key values[value1、value2...]:删除set中指定的元素
        例:srem set1 a c

    差集运算:

      sdiff key1 key2...:返回key1与key2中相差的元素,而且与key的顺序有关。即返回差集。

    交集运算:

      sinter key1 key2 key3...:返回交集

    并集运算:

      sunion key1 key2 key3...:返回并集

    扩展:

      scard key:获取set中元素的数量。

      srandmember key :随机返回set中的一个元素。

      sdiffstore destination key1 key2...:将key1、key2相差的元素存储在destination上
        例:sdiffstore set1 set2 set3  将set2与set3的差集元素存储到set1中。

      sinterstore destination key[key...]:将返回的交集存储在destination上
        例:siterstore set1 set2 set3  将set2与set3的交集元素存储到set1中。

      sunionstore destination key[key...]:将返回的并集存储在destination中
        例:sunionstore set1 set2 set3  将set2与set3的并集元素存储到set1中。

  有序set集合:

    有序且不重复。有序set集合专门用来做排行榜。

    赋值:

      zadd key score member score2 member2...:将所有元素以及该元素的分数存放到sorted-set中。若该元素已经存在,则会用新的分数替换原有的分数。返回值是新加入到集合中的元素个数,不包含之前已经存在的元素。
        例:zadd set1 1000 zhangsan 100 lisi 10 王五

    查看:

      zscore key member:返回指定元素的分数。
        例:zscore set1 zhangsan

      zcard key : 获取集合中的元素数量
        例:zcard set1

      zrange key start end[withscores]:范围查询。获取集合中脚标为start-end的元素,[withscores]参数表明返回的元素包含分数。
        例:zrange set1 0 -1  查询所有元素。正序排列。由小到大
          zrange set1 0 -1 withscores  查询所有元素。并且带有各自的分数。正序。由小到大

      zrevrange key start end[withscores]:范围查询。获取集合中脚标为start-end的元素,[withscores]参数表明返回的元素包含分数。
        例:zrevrange set1 0 -1  查询所有元素。倒序排列。由大到小
          zrevrange set1 0 -1 withscores  查询所有元素。并且带有各自的分数。倒序。由大到小

    删除:

      zrem key member[member...]:删除集合中指定元素。可以指定多个。
        例:zrem set1 zhangsan lisi

      zremrangebyrank key start stop:按照排名范围删除元素。
        例:zremrangebyrank set1 0 1  删除前俩名

      zremrangebyscore key min max:按照分数范围删除元素。
        例:zremrangebyscore set1 50 500  删除分数在50到500之间的元素

    扩展:

      zrangebyscore key min max[withscores][limit offset count]:返回分数在min-max的元素并按照分数从低到高排序。[withscores]:显示分数;[limit offset count]:offset,表明从脚标为offset的元素开始,并返回count个元素。
        例:zrangebyscore set1 50 500  返回分数在50-500之间的元素。
          zrangebyscore set1 50 500 withscores  返回分数在50-500之间的元素。加上分数。
          zrangebyscore set1 50 500 withscores limit 0 1  返回分数在50-500之间的元素。加上分数。并且只查前1个元素。

      zincrby key increment member:设置指定成员的增加分数。返回更改后的分数
        例:zincrby set1 10 zhangsan  给zhangsan增加10分。

      zcount key min max: 获取分数在min-max之间的元素。
        例:zcount set1 50 500  计算50-500分数之间的元素由多少

      zrank key member:返回成员在集合中的排名。索引(从小到大)
        例:zank set1 zhangsan  返回zhangsan的排名。

      zrevrank key member:返回元素在集合中的排名。索引(从大到小)
        例:zrevrank set1 zhangsan  返回zhangsan的排名。

  通用命令:

    keys pattern:获取所有与pattern匹配的key,返回所有与该key匹配的keys。
      通配符:
        *:表示任意一个或多个字符。
        ?:表示任意一个字符。
      例:keys * 查询所有的key
        keys ???? 查询key长度是四位的key名。
        keys *name* 查询key名包含name的key名。

    del key1 key2...:删除指定的key。可以指定多个。

    exites key:判断该key是否存在,1代表存在。0代表不存在。

    rename key newkey:为当前的key重命名。

    type key:获取指定key的类型。该命令将以字符串的格式返回。返回的字符串为string、list、set、hash和zset。如果key不存在,则返回none。

  设置key有效时间:

    expire key:设置过期时间。单位:秒

    ttl key:获取该key所剩的超时时间,若没有设置超时,返回-1。若返回-2,表示超时不存在。

  消息订阅与发布:

    subscribe channel:订阅频道。
      例:subscribe mychat 订阅mychat这个频道。

    psubscribe channel*:批量订阅频道。
      例:psubscribe s* 订阅以s开头的频道。

    publish channel content:在指定的频道中发布消息。
      例:publish mychat 'abcdefg'

  多数据库:

    Redis的数据库已经提前创建好了,默认有16个数据库。数据库的名字是0,1,2...15号数据库。在redis上所做的所有数据操作,都是默认在0号数据上操作的。数据库与数据库之间,是不能共享键值对的。

    切换数据库:select 数据库名(1,2,3...15)

    把某个键值对进行数据库的移植:move key 1:将key键移植到1号数据库中。

    清空当前数据库:flushdb

    清空所有的数据库内容:flushall

  事物:
    mysql的事物是为了保证数据完整性,安全。

    Redis的事物是为了进行redis语句的批量化执行。

    multi:开启事物,用于标记事物的开始,其后执行的命令都将被存入命令队列,知道执行EXEC时,这些命令才会被原子的执行。
      类似与关系型数据库中的:begin transaction

    exec:提交事物,类似与关系型数据库中的:commit

    discard:事物回滚,类似与关系型数据库中的:rollback

  了解命令:

    ping:返回PONG为已成功连通

    echo:在命令行打印一些内容  echo hehe

    select:切换数据库  select 1

    quit:退出客户端。等同于:Ctrl+C

    dbsize:返回当前数据库中key的数量。

    info:获取服务器的信息和统计。

  持久化:把数据保存在硬盘上。

    关系型数据库MySQL-持久化:

      任何的增删改语句,都是在硬盘上做的操作。
      断电以后,硬盘上的数据还是存在。

    非关系型数据库Redis-持久化:

      默认情况下,所有的增删改,数据都是在内存中进行操作。
      断电以后,内存中的数据不存在。redis的部分数据会丢失,丢失的数据时保存在内存中的数据。所以Redis是存在持久化操作的。

    Redis有俩种持久化策略:

      RDB:是Redis的默认持久化机制。RDB相当于照快照,保存的是一种状态。

        优点:
          1、快照保存数据速度极快,还原数据速度极快。
          2、适用于灾难备份。

        缺点:
          1、小内存机器不适合使用。因为RDB机制符合要求就会照快照。(随时随地启动)会占用部分系统资源(突然的占用),很可能内存不足直接宕机。

        适用于:内存比较充裕的计算机。

        RDB何时进行照快照:
          1、服务器正常关闭时,照快照。
          2、key满足一定条件时,照快照。

        配置说明:
          1、save 900 1:每900秒至少有一个key发生变化,则dump内存快照。
          2、save 300 10:每300秒至少有10个key发生变化,则dump内存快照。
          3、save 60 10000:每60秒至少10000个key发生变化,则dump内存快照。

      AOF:

        使用日志功能保存数据的操作。适用于:内存比较小的计算机。

        每秒同步(默认):每秒进行一次AOF保存数据。安全性低,但比较节省系统资源。

        每修改同步:只要有key变化语句,就进行AOF保存数据。比较安全,但极为浪费系统资源。

        不同步:不进行任何持久化操作。不安全。

        AOF操作:
          只会保存导致key变化的语句。

        AOF配置:

          AOF默认时关闭的。

          开启AOF:
            1、appendonly yes
            2、放开 appendfsync always

          always:每次有数据修改发生时都会写入AOF文件。
          everysec:每秒同步一次,该策略为AOF的缺省策略。
          no:从不同步,高效但数据不会被持久化。

        优点:
          持续性占用极少量的内存资源。

        缺点:
          1、日志文件会特别大,不适用于灾难恢复。
          2、恢复效率远远低于RDB。

  Jedis:

    所有的Redis命令,Jedis都有对应的方法。

    Java中连接Redis数据库需要开启Linux中Redis对应的端口号:

      /shin/iptables -I INPUT -p tcp --dport 6379 -j ACCEPT
      /etc/rc.d/init.d/iptables save

    单实例连接Redis数据库:Jedis jedis=new Jedis("IP",6379);

    Jedis连接池:

JedisPoolConfig config = new JedisPoolConfig();//设置连接池的配置对象
//可以不设置池的参数
config.setMaxTotal(int);//设置池中最大连接数
config.setMaxIdle(int);//设置空闲时池中包有的最大连接数
JedisPool pool = new JedisPool(config,"IP",6379);//设置连接池对象
Jedis jedis=pool.getResource();//从池中获取连接对象。
jedis.get("name");
jedis.close();//连接归还池JedisPool中

    JedisUtils:

public class JedisUtils{
    //定义一个连接池对象
    private final static JedisPool POOL;
    static{//初始化操作
        JedisPoolConfig config = new JedisPoolConfig();
        config.setMaxTotal(int);
        config.setMaxIdle(int);
        POOL = new JedisPool(config,"IP",6379);
    }
    
    //从池中获取连接
    public static Jedis getJedis(){
        return POOL.getResource();
    }
}

 

posted @ 2019-02-27 00:29  水痕灬  阅读(166)  评论(0编辑  收藏  举报