zoukankan      html  css  js  c++  java
  • Redis基础

    Redis

    一. 什么是Redis?

    Redis是一套分布式高速缓存系统.

    RedisMongoDB,MemCache都是属于NoSQL思想的实现,称之为非关系型数据库.

    二. 为什么需要Redis?

    过去是单机型数据库的天下,各大数据库提供商都在努力提高单机型数据库的效率与安全性.其中OracleSQL Server以及MySQL更是其中的佼佼者.

    随着互联网产业的高速发展,传统的数据库容量不断增大,并发读写量不断提高,以下三个方面的问题出现:

    1. 数据量过大(分表分库)
    2. 读写次数过多(读写分离)

    三. Redis有什么用?

    传统的关系型数据库每秒中写入大概23,读稍微多一点.Redis大约每秒写8w,11w.

    关系型数据库保存数据以表形式,对字段类型进行限制,Redis使用KV保存方式,值的类型更加多元化.

    Redis为系统提供更高速,更多元,更实时的数据.

    四. Redis的特点

    1. 支持数据持久化

    可以将缓存在内存中的数据保存在磁盘中,重启后仍然可以使用数据.

    2. 数据类型多元化

    不仅提供简单的KV形式,还有提供list,set,zset,hash等数据结构的储存.

    3. 支持数据备份

    Master – Slave模式数据备份.

    五. CAP理论

    1.概念

    1.1) Consistency(一致性)

    数据一致更新,所有数据变动都是同步的

    1.2) Availability(可用性)

    好的响应性能

    1.3) Partition tolerance(分区容忍性)

    可靠性

    2.总结

    2.1任何分布式系统只可同时满足二点,没法三者兼顾

    2.2只能分成满足CA,CP,AP三种情况

    a) CA: 单点集群.满足一致性和可用性,分区容忍性不强.

    b) CP: 满足一致性,分区容忍性,但可用性不高.

    c) AP: 满足可用性,分区容忍性,但一致性较差.

    六. BASE思想

    1. 关系数据库的ACID模型 

    a) Atomicity原子性:一个事务中所有操作都必须全部完成,要么全部不完成。

    b) Consistency一致性. 在事务开始或结束时,数据库应该在一致状态。

    c) Isolation隔离层. 事务将假定只有它自己在操作数据库,彼此不知晓。

    d) Durability. 一旦事务完成,就不能返回。

    总结: 高一致性 + 可用性 但是很难进行分区:

    2. BASE模型反ACID模型

    完全不同ACID模型,牺牲高一致性,获得可用性或可靠性:

    a) Basically Available基本可用。支持分区失败(e.g. sharding碎片划分数据库)

    b) Soft state软状态 状态可以有一段时间不同步,异步。

    c) Eventually consistent最终一致,最终数据是一致的就可以了,而不是时时高一致。

    七. 下载安装

    1.下载地址:

    英文官网: https://redis.io/

    中文官网http://www.redis.cn/

    2.将下载好的tar.gz拷贝到Linux: /usr/local目录下

    3.解压缩并且进入目录/usr/local/redis-xxx

    4.安装gcc-c++

    yum install gcc-c++

    5.执行安装命令

    make&&make install

    八. 初始配置

    1.配置文件位置

    /usr/local/redis-xxx/redis.conf

    2.备份配置文件

    /redis-conf-copy/redis.conf

    3.修改为后台运行

    将备份的配置文件中daemonize no修改为yes

    4.进入命令目录并启动服务以及找到配置文件位置

    cd /usr/local/bin/

    redis-server /redis-conf-copy/redis.conf

    5.打开新的命令终端查看服务是否启动

    ps -ef|grep redis

    redis默认端口6379

    6.进入redis

    redis-cli -p 6379

    7.测试redis是否正常

    输入ping,会收到回复pong

    8.测试Key-Value保存

    set key value

    get key

    9.测试读写速度

    执行benchmark

    9.停止服务

    SHUTDOWN

    Exit

    九. 内存数据库

    1.Redis有多少个数据库?

    redis默认存在16个库,每个库拥有自己唯一的下标,类似于数组从0开始,默认使用0号库.

    2.如何切换Redis数据库

    select 下标

    3.获得当前数据库中key数量

    dbsize

    测试插入后的数据库key数量

    set k1 v1

    set k2 v2

    set k3 v3

    4.获得所有的key内容

    keys *

    5.占位符?

    keys i?

    获得以i开头所有的key

    keys ?1

    获得以1结尾所有的key

    6.清除本数据库所有的key

    flushdb

    7.清除16个库中所有的key

    flushall

    Redis命令大全: redisdoc.com

    十. key关键字

    1. exists

    判断是否存在某个key

    存在返回1,不存在返回0.

    2. move

    移动到其他的库

    3. ttl

    Time to live 过期时间

    返回过期时间还有多少秒,返回-1 永不过期, 返回-2 已经过期.

    设置过期时间: expire key second

    4. type

    获得Key的类型

    十一. 五大数据类型

    Redis的数据类型相较于其他NoSQL实现更加多元化,虽然同样属于KV类型非关系型数据库,但是value的类型有以下五种:

    String: 字符串,用于网页标题,点赞数量等等...

    List: 有序列表

    Set: 散列集合

    Zset: 有序集合

    Hash: Redis对象

    1. String(字符串)

    最基本的数据类型,二进制安全,redis中一个string类型的value最大可以是512m.

    二进制安全指的,可以保存二进制文件数据,也可以保存对象序列化信息.

    set/get/del/append/strlen

    1) del

    删除key

    2) append

    找到key并在value后追加

    3) strlen

    获得字符串的长度

    4) incr

    自增,要求数字

    5) decr

    自减

    6) incrby

    指定增量自增

    语法: incrby key 增量

    7) decrby

    指定减量自减

    语法: incrby key 减量

    8) getrange

    获得范围内数据(substring)

    语法: getrange key beginIndex endIndex

    9) setrange

    从指定位置开始替换,替换相同数量的内容(replace)

    语法: setrange key beginIndex content

    10) setex

    设置kv同时指定存活时间

    语法: setex key time value

    11) setnx

    key不存在时就设置值

    语法: setnx key value

    12) mset

    批量设置kv

    13) mget

    批量通过key获得value

    14) msetnx

    都不存在时批量设置

    2. List(列表)

    简单的字符串列表,按照插入顺序进行排序,可以添加元素到头部或者尾部.

    lpush/rpush/lrange/lpop/rpop/lindex/irem/ltrim/rpoplpush/lset/linsert

    1) lpush

    从集合左侧推入数据

    2) rpush

    从集合右侧推入数据

    3) lrange

    获得集合数据

    4) lpop

    左出栈

    5) rpop

    右出栈

    6) lindex

    按照下标获得元素

    7) lrem

    删除指定个数的指定值

    语法: irem count value

    8) ltrim

    将列表中的元素截取一部分,重新赋值给key

    9) rpoplpush

    语法: rpoplpush list1 list2

    集合1右出数据,集合2左入数据

    10) lset

    语法: lset list index value

    插入值到指定下标

    11) linsert

    在指定值 /后 插入指定值

    语法: linsert list  before/after  target  value

    总结: 列表可以对于左右操作十分方便快速,中间数据操作效率低下.

    3. Set(集合)

    字符串类型的无序集合,散列.

    sadd/smembers/sismembers/scard/srem/srandmember/spop/smove/sdiff/sinter/sunion

    1) sadd

    将数据插入集合中

    语法: sadd key value[]

    2) smembers

    获得集合中的数据

    语法: smembers key

    3) sismembers

    查询集合中是否存在数据

    语法: sismembers

    4) scard

    获得集合中元素个数

    5) srem

    移除指定元素

    6) srandmember

    随机抽取几个数字

    7) spop

    随机出栈

    8) smove

    从一个集合移动数据到另一个集合

    语法: smove set1 set2 value

    9) sdiff

    差集

    10) sinter

    交集

    11) sunion

    并集

    4. Hash(哈希,类似于java中的java.util.Map)

    Hash是一个键值对集合,是一个fieldvalue的映射表,hash特别适合保存对象.

    类似于java中的: Map<String,Object>

    仍然是KV模式,但是V是一个键值对

    hset/hget/hmset/hgetall/hdel/hlen/hexists/hkeys/hvals/hincrby/hincrbyflout/hsetnx

    1) hset

    2) hget

    3) hmset

    4) hmget

    5) hgetall

    6) hdel

    7) hlen

    8) hexists

    9) hkeys

    10) hvals

    11) hincrby

    12) hincrbyflout

    13) hsetnx

    5. Zset(sorted set: 有序集合)

    有序集合,每个值关联一个double类型的分数.

    之前的setk1 v1 v2

    现在的zsetk1 score1 v1 score2 v2

    zadd/zrange/zrangebyscore/zrem/zcard/zcount/zrank/zscore/zrevrank/

    zrevrange/zrevrangebyscore

    1) zadd

    2) zrange

    withscores

    3) zrangebyscore

    (

    limit

    4) zrem

    5) zcard

    6) zcount

    7) zrank

    8) zscore

    9) zrevrank

    10) zrevrange

    11) zrevrangebyscore

    (

    limit

    十二. 配置文件

    1) units单位

    2) include包含

    3) general通用

    daemonize: yes/no

    守护进程,作用允许redis在关闭命令终端时继续在后台工作.

    databases: integer

    设置redis启动时创建内存数据库的数量.

    pidfile:

    线程管道文件

    port: 6379

    端口设置

    tcp-backlog: 511

    连接队列

    backlog队列总和 = 未完成三次握手队列 + 已经完成三次握手队列.

    bind: 127.0.0.1

    绑定服务器

    timeout: 0

    对于客户端连接到redis,可以采用超时关闭连接模式以节约内存,默认连接超时时间0,表示永不关闭.

    开发中建议设置为0,生产中建议配置为3005分钟后断开

    tcp-keepalive

    Redis集群心跳检测,每隔一段时间发送心跳检测,获得集群中其他redis是否依然在运行.

    loglevel: notice

    日志等级: 默认 notice(通知),开发时允许调成debug

    logfile: “”

    日志文件位置

    建议设置logfile stdout系统输出设备

    syslog-enabled: no

    系统日志开关

    sylog-ident: redis

    系统日志开头文字(标识)

    4) snapshotting快照

    5) replication复制

    6) security安全

    config get requirepass: 获得必须的密码

    config get dir: 获得当前打开命令终端的路径

    一部分日志会保存到当前打开终端的路径下.

    config set requirepass: 设置必须的密码

    设置完密码后redis需要必须的密码验证才可以使用.

    如果希望解除密码验证,只需要将必须密码设置为””即可.

    auth your-password

    7) limits限制

    Maxclients: 10000

    最大连接客户端

    Maxmemory:

    最大内存

    Maxmemory-policy: noeviction

    过期策略算法:

    Lru:最近最少使用

    Random: 随机

    Ttl: 有限时间内

    单词解释:

    Volatile: 保护

    Allkeys: 非保护

    缓存过期策略:

    Noeviction(默认): 不进行移除,永不过期

    Volatile-lru: 使用LRU算法移除key,只作用于设置了过期时间的key

    Allkeys-lru: 使用LRU算法移除key

    Volatile-random: 随机移除, 只作用于设置了过期时间的key

    Allkeys-random: 随机移除

    Volatile-ttl: 移除那些ttl值小的key,即那些最近要过期的key.

    Maxmemory-samples: 5

    由于LRUTTL算法都非精确算法,可能存在误差,可以使用测试计算误差.

    设置样本数量,默认5.

    减少测试样本数量会降低测试准确度.

    增加测试样本数量会增加测试时间.

    8) append only mode追加

    十三. 持久化

    1.RDB

    1.1 什么是RDB?

    RDBRedis Database的简称.

    1.2 RDB有什么用?

    在指定的时间间隔内,将内存中的数据集快照写入磁盘.

    Snapshot快照,它恢复时时将快照文件直接读到内存里.

    1.3 RDB的原理

    Redis会单独创建(fork)一个子进程来进行持久化,会将数据写入到一个临时文件中,带持久化过程都结束了,再用这个临时文件替换上次持久化好的文件.整个过程中,主进程是不进行任何IO操作的,这就确保了主进程极高的性能.如果需要对大规模的数据进行恢复,且对数据的完整性不是非常敏感,那么RDB方式要比AOF方式更加高效.RDB方式的缺点是最后一次持久化之后的数据可能丢失.

    1.4 什么是fork?

    复制一个与当前进程一样的进程.新进程的所有数据(变量,环境变量,程序计数器等)数值都和原进程一致,但是是一个全新的进程,并作为进程的子进程.子进程将内存中的数据通过IO保存到硬盘中进行持久化,保存的文件名为dump.rdb.

    1.5 如何使用RDB持久化?

    1.5.1打开配置文件redis.cnf

    1.5.2找到SNAPSHOTTING

    1.5.3持久化备份机制

    save <second> <change>

    保存 变更次数

    以上设置为在多长时间内发生变更次数达到多少就进行保存.

    默认值:

    save 900 1 15分钟内有一次

    save 300 10 5分钟10

    save 60 10000  1分钟内达到1万次

    以上内容也可以进行自定义设置

    1.5.4禁用RDB

    save “”

    禁用后Redis就不能进行RDB持久化,请慎用此设置.

    1.5.5数据恢复

    dump.rdb文件放置在启动位置即可自动恢复.

    1.5.6立即备份

    Redis命令行输入save可以立即备份

    1.5.7遇到后台持久化错误时是否可以继续写操作

    stop-writes-on-bgsave-error yes

    有数据运维或RedisDBA可以允许关闭,否则会影响数据一致性.

    1.5.8是否压缩持久化文件

    rdbcompression yes

    压缩节约硬盘空间,压缩式需要浪费CPU,不压缩反之.

    1.5.9压缩验证算法

    rdbchecksum yes

    对备份数据进行验证,需要提示Redis10%的性能消耗.

    1.5.10备份文件名及路径

    dbfilename dump.rdb

    dir ./  --当前路径

    1.5.11总结

    一. 以下三种方式可以 产生/更新 持久化备份文件.

    1. fork进程触发
    2. save命令
    3. flushall

    shutdown也可以进行持久化备份,生产中一般不会经常运行此命令.

    二. 如何恢复?

    将文件copy到启动目录就可以进行恢复,生产中一般放置到启动目录下.

    三. 优势与劣势分析

    优势: 适合大规模的数据恢复

    劣势: 数据的一致性不高,fork进程启动时内存2倍膨胀.

    2.AOF

    2.1什么是AOF?

    AOFAppend Only File的简称.

    AOFRDB协作运行,不产生冲突.

    2.2为什么需要AOF?

    弥补RDB的劣势.

    2.3AOF的原理

    以日志的形式来记录每个写操作,redis执行过的所有指令记录下来(读操作不记录),只许追加文件但不可以改写文件,redis启动之初会读取该文件重新构建数据,换言之,redis重启的话就根据日志文件的内容将写指令从前到后执行一次以完成数据的恢复.

    使用异步方式进行记录

    2.4 如何使用AOF?

    复制并且重命名aof文件.

    2.4.1默认关闭AOF

    appendonly no

    手动设置为yes

    2.4.2默认文件名称

    appendfilename "appendonly.aof"

    2.4.3开启服务进入Redis立即产生appendonly.aof文件

    2.4.4设置kvredis

    2.4.5清空所有数据库并且退出redis

    2.4.6查看appendonly.aof文件内容

    2.4.7移除rdb文件确保不会进行RDB恢复

    2.4.8删除FLUSHALL指令

    生产环境中一般是不允许手动修改appendony.aof.

    2.4.9启动并且进入Redis,查看key

    2.4.10启动是读取备份文件的优先级

    Redis启动时首先会去读取aof文件,没有aof再去读取rdb文件.

    可以将adf文件故意加入错误内容,在同时有rdbaof文件的Redis启动进行测试,如果报错说明优先读取aof,不报错说明优先读取rdb文件.

    备份被写坏的aof文件,再使用redis-check-aof –fix appendonly.aof命令,可以智能检测aof文件的错误并且修改.

    2.4.11同步文件策略

    # appendfsync always: 同步持久化

    每次发生数据改变立即记录到磁盘,性能较差但完整性最好.

    appendfsync everysec: 每秒记录(默认设置)

    性能较好,但是如果在宕机的1秒内保存的数据,有可能丢失.

    # appendfsync no: 不持久化

    2.4.12为什么需要重写?

    AOF采用追加的方式,AOF文件越来越大时,需要对文件进行精简压缩.当文件大小超过所设定的阈值时,Redis就会启动AOF文件内容压缩.将重复的相同的操作指令,进行优化,使文件内容缩小,但是运行结果相同.也可以使用指令bgrewriteaof.

    2.4.13重写的机制

    AOF持续增长到一定大小时,fork出一条新的进程来将文件重写(先产生临时文件,最后再rename).遍历新进程的内存中数据,每条记录有一条的Set语句.重写AOF文件并没有读取旧的AOF文件,而是将整个内存中的数据库内容用命令的方式重写了一个新的AOF文件,这点和快照有所类似.

    Redis会记录上次重写时的AOF大小,默认是当AOF文件大小时上次rewrite后大小的一倍并且文件大小超过64m时触发.

    no-appendfsync-on-rewrite no

    重写时可以允许appendfsync,默认no,保证数据安全性

    auto-aof-rewrite-percentage 100

    auto-aof-rewrite-min-size 64mb

    设置重写的基准值

    2.4.14总结

    优势: 保存数据一致性非常高

    劣势:

    备份时采用每秒追加,或者同步追加功耗巨大

    相同数据aof文件要远远大于rdb文件,并且恢复速度要慢恢复时间要久.

    十四. 事务

    1. 什么是redis的事务?

    可以一次性执行多个命令,本质上是一组命令的集合.一个事务中的所有命令都会序列化,会按照顺序的执行而不会被其他命令插入,不允许加塞.(类似于批处理)

    2. redis如何保证一致性

    如果多个redis命令操作需要保证一致性,那么就需要开启redis事务.

    3. redis的事务能做什么?

    一个队列中,一次性,顺序性,排他性的执行一系列的命令.

    4. 如何使用redis事务?

    4.1事务常用命令

    4.1.1multi

    标记一个事务块的开始

    4.1.2exec

    执行所有事务块内的命令

    4.1.3discard

    取消,放弃执行事务块内的所有命令

    4.1.4watch key [key]

    一个或多个key,如果在事务执行前被监key被其他人操作发生改动,那么事务将被打断.(类似于Git提交冲突)

    4.1.5unwatch

    取消watch命令对所有key的监视

    4.2事务操作中的一些情况

    关键字: QUEUED 队列

    (redis事务操作中指操作入队)

    4.2.1Case1: 正常执行

    4.2.2Case2: 放弃事务

    4.2.3Case3: 一票否决(没有成功添加队列)

    4.2.4Case4: 待定审核(添加队列成功但执行错误)

    4.2.5Case5: watch监控

    乐观锁:

    不进行锁定,只在出现问题是进行类似于版本控制器的冲突解决.

    提交版本必须大于当前版本才能执行.

    悲观锁:

    锁定数据,不允许其他线程修改,能很好的保证数据一致性,但会影响并发性能.

    : 行锁 表锁 读锁 写锁

    watch案例:信用卡余额与应还金额.

    1.正常的操作
    2.多线程冲突操作

    线程一监听money

    线程二修改money

    线程一开启事务,并且修改money,执行事务时会出现失败提示返回nil

    3.解决多线程冲突操作

    线程一监听money

    线程二修改money,此时线程二应该通知线程一

    线程一开启事务前关闭监听等待线程二修改完成再次加入监听,并且修改money,执行事务

    4.3总结:

    1.一旦执行exec那么之前的watch都会被清空

    2.不保证原子性,redis命令集中一条执行失败,其余的也能执行成功.

    3.没有回滚机制

    十五. 主从复制

    replication

    十六. Jedis

    redis 远程连接方法

    解决方法

    1、修改redis服务器的配置文件

    vi redis.conf

    注释以下绑定的主机地址

    # bind 127.0.0.1

    vim  redis.conf

    bind  0.0.0.0

    protected-mode   no

    2、修改redis服务器的参数配置

    修改redis的守护进程为no,不启用

    127.0.0.1:6379> config  set   daemonize  "no"

    OK

    修改redis的保护模式为no,不启用

    127.0.0.1:6379> config   set   protected-mode"no"

    OK

    或者

    config set requirepass 123 ->123是密码

    注意:开启 6379端口

     

    3、远程连接

    $ redis-cli -h 138.138.138.138  -p  6379 

    redis>ping

    PONG

    1.如何使用Jedis?

    springboot工程中添加jedis的依赖

    2.常用命令

    2.1测试

    ping()

    2.2设置string

    set(String key,String value);

    2.3根据key获得值

    get(String name);

    2.4获得所有的key

    getkeys(“pattern”)

    3.事务

    Jedis j = new Jedis(“ip”,port);

    Transactional  tran = j.multi();

    4.存取对象

    4.1使用hash方式保存

    4.2使用字节方式保存

    IDEA如何将对象产生序列化ID

    将自动产生序列化ID勾选,在类名上使用ALT+回车即可产生序列化ID

    4.3使用json方式保存

  • 相关阅读:
    Python3 input() 函数
    Python3 enumerate() 函数
    Python3 ascii() 函数
    Python3 sorted() 函数
    css sprite
    Java 理论与实践: 并发集合类
    关于 Java Collections API 您不知道的 5 件事,第 1 部分
    Treasure! Free Mobile Design Resources
    Indigo Studio
    ionic:Build mobile apps faster with the web technologies you know and love
  • 原文地址:https://www.cnblogs.com/tysl/p/10964820.html
Copyright © 2011-2022 走看看