Redis
Redis 是内存数据库,是nosql数据库。 基于key value存储的数据,key只能是string类型, v 可以使多种类型。
关系型数据库的索引机制; btree
SAP HANA ERP 中的HANA是内存数据库。
SAP 介绍: http://baijiahao.baidu.com/s?id=1642447333409744589&wfr=spider&for=pc
从模块组成上看,SAP R/2可以称为ERP软件的雏形,因为除了财务模块,SAP R/2还增加了生产和进销存模块,以及人力资源管理模块。 可以抽空看看产品演示。
https://visualgo.net/zh 麻省理工:算法导论:网易公开课 清华大学:数据结构:学堂在线 <<db2 教材 官方>> join 《深入理解计算机系统》 《MR设计模式》 《nosql精粹?》
Redis 开源的(BSD协议),使用ANSI C 编写,基于内存的且支持持久化,高性能的Key-Value的NoSQL数据库 支持数据结构类型丰富,有如 字符串(strings), 散列(hashes), 列表(lists), 集合(sets), 有序集合(sorted sets) 与范围查询, bitmaps, hyperloglogs 和 地理空间(geospatial) 索引半径查询。 丰富的支持主流语言的客户端,C、C++、Python、Erlang、R、C#、Java、PHP、Objective-C、Perl、Ruby、Scala、Go、JavaScript 用途:缓存(StackOverFlow)、数据库(微博)、消息中间件(微博) 官方网站: http://www.redis.io a=1 a=k a=(1,3,98)a={x=11,w=88} 客户端完成业务
行业经验和项目报价和评议比较重要。
版本: 分布式 3.18; 伪分布式3.0一下,2.8.18 单节点部署 安装gcc和tcl准备编译环境 yum install -y gcc tcl /root/software tar -zxvf redis-2.8.18.tar.gz cd redis-2.8.18 make && make PREFIX=/opt/sxt/redis install ## 编译复制到opt下 cd /opt/sxt/redis/ vi /etc/profile export REDIS_HOME=/opt/sxt/redis export PATH=$JAVA_HOME/bin:$PATH:$HADOOP_HOME/bin:$HADOOP_HOME/sbin:$HBASE_HOME/bin:$REDIS_HOME/bin source /etc/profile cd ~/software/redis-2.8.18 cd utils/ [root@node1 utils]# ./install_server.sh ## 安装redis 服务端 实例。 Welcome to the redis service installer This script will help you easily set up a running redis server Please select the redis port for this instance: [6379] Selecting default: 6379 Please select the redis config file name [/etc/redis/6379.conf] Selected default - /etc/redis/6379.conf Please select the redis log file name [/var/log/redis_6379.log] Selected default - /var/log/redis_6379.log Please select the data directory for this instance [/var/lib/redis/6379] Selected default - /var/lib/redis/6379 Please select the redis executable path [/opt/sxt/redis/bin/redis-server] Selected config: Port : 6379 Config file : /etc/redis/6379.conf Log file : /var/log/redis_6379.log Data dir : /var/lib/redis/6379 Executable : /opt/sxt/redis/bin/redis-server Cli Executable : /opt/sxt/redis/bin/redis-cli Is this ok? Then press ENTER to go on or Ctrl-C to abort. Copied /tmp/6379.conf => /etc/init.d/redis_6379 Installing service... Successfully added to chkconfig! Successfully added to runlevels 345! Starting Redis server... Installation successful! ## 一个redis服务可以再一个节点上有多个实例,(选择不同的通讯端口) ## 一个服务实例最多有16个数据库。 从0开始。 ## 查看帮助 [root@node1 utils]# redis-server -h [root@node1 utils]# redis-cli -h
[root@node1 ~]# redis-cli 127.0.0.1:6379> help set SET key value [EX seconds] [PX milliseconds] [NX|XX] summary: Set the string value of a key since: 1.0.0 group: string 127.0.0.1:6379> set k1 abc OK 127.0.0.1:6379> get k1 "abc" 127.0.0.1:6379> set k2 5 OK 127.0.0.1:6379> get k2 "5" 127.0.0.1:6379> keys * 1) "k1" 2) "k2" 127.0.0.1:6379> SETNX k1 dww ## nx 不存在时才增加(只能添加) (integer) 0 127.0.0.1:6379> get k1 "abc" 127.0.0.1:6379> set k1 dww xx OK 127.0.0.1:6379> get k1 "dww" 127.0.0.1:6379> set k2 sdlwlw xx ## 存在时才修改(只能修改) OK 127.0.0.1:6379> get k2 "sdlwlw" 127.0.0.1:6379> set k3 sdfdfs xx (nil) 127.0.0.1:6379> get k3 (nil) 127.0.0.1:6379> keys * 1) "k1" 2) "k2" 127.0.0.1:6379> type k1 string 127.0.0.1:6379> get k1 "dww" 127.0.0.1:6379> type k2 string 127.0.0.1:6379> get k2 "sdlwlw" 127.0.0.1:6379> set k3 99 OK 127.0.0.1:6379> type k3 string 127.0.0.1:6379> OBJECT encoding k2 "raw" 127.0.0.1:6379> OBJECT encoding k3 ## 属性,可以看到string是否适合位运算。 "int" 127.0.0.1:6379> get k3 "99"
127.0.0.1:6379> help MGET MGET key [key ...] summary: Get the values of all the given keys since: 1.0.0 group: string 127.0.0.1:6379> keys * 1) "k3" 2) "k1" 3) "k2" 127.0.0.1:6379> MSET k4 5 k5 abc k6 werw OK 127.0.0.1:6379> keys * 1) "k5" 2) "k6" 3) "k1" 4) "k4" 5) "k3" 6) "k2" 127.0.0.1:6379> MSETNX k6 dfsd k7 dkfd (integer) 0 127.0.0.1:6379> keys * 1) "k5" 2) "k6" 3) "k1" 4) "k4" 5) "k3" 6) "k2" 127.0.0.1:6379> MSETNX k7 dfsd k8 dkfd (integer) 1 127.0.0.1:6379> keys * 1) "k7" 2) "k5" 3) "k6" 4) "k1" 5) "k4" 6) "k8" 7) "k3" 8) "k2" 127.0.0.1:6379> MSETNX k9 eerw k8 ewrwe (integer) 0 127.0.0.1:6379> keys * 1) "k7" 2) "k5" 3) "k6" 4) "k1" 5) "k4" 6) "k8" 7) "k3" 8) "k2" 127.0.0.1:6379> set kab www OK 127.0.0.1:6379> keys * 1) "kab" 2) "k5" 3) "k4" 4) "k1" 5) "k3" 6) "k8" 7) "k2" 8) "k7" 9) "k6" 127.0.0.1:6379> keys ? ## 正则匹配一个字符 (empty list or set) 127.0.0.1:6379> keys ?? 1) "k5" 2) "k4" 3) "k1" 4) "k3" 5) "k8" 6) "k2" 7) "k7" 8) "k6" 127.0.0.1:6379> keys ??? ## 匹配三个字符 1) "kab" 127.0.0.1:6379> type k1 string 127.0.0.1:6379> STRLEN ke (integer) 0 127.0.0.1:6379> STRLEN k1 (integer) 3 127.0.0.1:6379> STRLEN k3 (integer) 2 127.0.0.1:6379> FLUSHALL ## 清空所有数据 OK 127.0.0.1:6379> keys * (empty list or set) 127.0.0.1:6379> set k21 werwe OK 127.0.0.1:6379> FLUSHDB ## 清空数据库 OK 127.0.0.1:6379> keys * (empty list or set) [root@node1 ~]# redis-cli -n 1 127.0.0.1:6379[1]> get k1 (nil) 127.0.0.1:6379[1]> keys * (empty list or set) 127.0.0.1:6379[1]> quit [root@node1 ~]# redis-cli 127.0.0.1:6379> keys * (empty list or set) 127.0.0.1:6379> get k1 (nil) 127.0.0.1:6379> set k1 a OK 127.0.0.1:6379> get ki (nil) 127.0.0.1:6379> get k1 "a" 127.0.0.1:6379> exit [root@node1 ~]# redis-cli -n 1 ##链接数据库1 127.0.0.1:6379[1]> get k1 (nil) 127.0.0.1:6379[1]> keys * (empty list or set) 127.0.0.1:6379[1]> quit [root@node1 ~]# redis-cli -n 0 127.0.0.1:6379> get k1 "a" 127.0.0.1:6379> set k2 99 OK 127.0.0.1:6379> STRLEN k2 (integer) 2 127.0.0.1:6379> set k3 999 OK 127.0.0.1:6379> STRLEN k3 (integer) 3 127.0.0.1:6379> set k4 中 ## xshell是utf-8 OK 127.0.0.1:6379> STRLEN k4 (integer) 3 127.0.0.1:6379> set k5 中 OK 127.0.0.1:6379> STRLEN k5 (integer) 3
[root@node1 ~]# redis-cli ## xhsell选择gbk编码链接时。 127.0.0.1:6379> set k5 中 OK 127.0.0.1:6379> STRLEN k5 (integer) 2
127.0.0.1:6379> [root@node1 ~]# redis-cli -n 0 127.0.0.1:6379> get k4 ##展示的是字节码 "\xe4\xb8\xad" 127.0.0.1:6379> [root@node1 ~]# redis-cli --raw ##原始数据类型显示 127.0.0.1:6379> get k4 中 127.0.0.1:6379> get k5 א 127.0.0.1:6379> get k4 中 127.0.0.1:6379> [root@node1 ~]# redis-cli 127.0.0.1:6379> EXISTS k5 (integer) 1 127.0.0.1:6379> get k1 "a" 127.0.0.1:6379> GETSET k1 b "a" 127.0.0.1:6379> get k1 "b" 127.0.0.1:6379> APPEND k1 bd (integer) 3 127.0.0.1:6379> get k1 "bbd" 127.0.0.1:6379> get k1 "bbd" 127.0.0.1:6379> append k1 werw (integer) 7 127.0.0.1:6379> get k1 "bbdwerw" 127.0.0.1:6379> GETRANGE (error) ERR wrong number of arguments for 'getrange' command 127.0.0.1:6379> help GETRANGE GETRANGE key start end summary: Get a substring of the string stored at a key since: 2.4.0 group: string 127.0.0.1:6379> GETRANGE k1 3 (error) ERR wrong number of arguments for 'getrange' command 127.0.0.1:6379> GETRANGE k1 3 -1 "werw" 127.0.0.1:6379> GETRANGE k1 -2 -2 "r" 127.0.0.1:6379> get k1 "bbdwerw" 127.0.0.1:6379> INCR k1 (error) ERR value is not an integer or out of range 127.0.0.1:6379> FLUSHALL OK 127.0.0.1:6379> set k1 99 OK 127.0.0.1:6379> INCR k1 ## 数值类型自增长 (integer) 100 127.0.0.1:6379> INCR k1 (integer) 101 127.0.0.1:6379> INCR k1 (integer) 102 127.0.0.1:6379> DECR k1 (integer) 101 127.0.0.1:6379> DECR k1 (integer) 100 127.0.0.1:6379> INCRBY k1 5 (integer) 105 127.0.0.1:6379> INCRBY k1 5 ## 数值类型自增长步长 (integer) 110 127.0.0.1:6379> INCRBYFLOAT 5.5 (error) ERR wrong number of arguments for 'incrbyfloat' command 127.0.0.1:6379> INCRBYFLOAT k1 5.5 "115.5" 127.0.0.1:6379> SETBIT k1 1 1 (integer) 0 127.0.0.1:6379> get k1 "q15.5" 127.0.0.1:6379> get k1 "q15.5" 127.0.0.1:6379> FLUSHALL OK 127.0.0.1:6379> SETBIT k1 1 1 ## 位图数据 1byte 01000000 sacii 表的64 = @ (integer) 0 127.0.0.1:6379> get k1 "@" 127.0.0.1:6379> help SETBIT SETBIT key offset value summary: Sets or clears the bit at offset in the string value stored at key since: 2.2.0 group: string 127.0.0.1:6379> SETBIT k1 7 1 1byte 01000001 (integer) 0 127.0.0.1:6379> get k1 "A" 127.0.0.1:6379> SETBIT k1 9 1 2byte 01000001 01000000 A@ (integer) 0 127.0.0.1:6379> get k1 "A@" 127.0.0.1:6379>
127.0.0.1:6379> FLUSHALL OK 127.0.0.1:6379> SETBIT k1 1 1 (integer) 0 127.0.0.1:6379> get k1 "@" 127.0.0.1:6379> SETBIT k1 7 1 (integer) 0 127.0.0.1:6379> get k1 "A" 127.0.0.1:6379> SETBIT k1 9 1 (integer) 0 127.0.0.1:6379> get k1 "A@" 127.0.0.1:6379> GETBIT k1 9 (integer) 1 127.0.0.1:6379> GETBIT k1 1 (integer) 1 127.0.0.1:6379> GETBIT k1 7 (integer) 1 127.0.0.1:6379> GETBIT k1 6 (integer) 0 127.0.0.1:6379> BITPOS k1 1 (integer) 1 127.0.0.1:6379> BITPOS k1 1 0 0 (integer) 1 127.0.0.1:6379> BITPOS k1 1 0 1 (integer) 1 127.0.0.1:6379> SETBIT k1 1 0 (integer) 1 127.0.0.1:6379> BITPOS k1 1 0 1 (integer) 7 127.0.0.1:6379> SETBIT k1 7 0 (integer) 1 127.0.0.1:6379> BITPOS k1 1 0 1 (integer) 9 ### 解释 0000000 01000000 127.0.0.1:6379> BITPOS k1 1 0 1 查找1在0~1的字节索引中的二进制位索引(偏移量)
127.0.0.1:6379> FLUSHALL OK 127.0.0.1:6379> SETBIT k1 1 1 (integer) 0 127.0.0.1:6379> SETBIT k2 7 1 (integer) 0 127.0.0.1:6379> BITOP and k3 k1 k2 (integer) 1 127.0.0.1:6379> get k3 "\x00" 127.0.0.1:6379> BITOP or k4 k1 k2 (integer) 1 127.0.0.1:6379> get k4 "A"
127.0.0.1:6379> help BITCOUNT BITCOUNT key [start] [end] summary: Count set bits in a string since: 2.6.0 group: string 127.0.0.1:6379> SETBIT k1 7 1 (integer) 0 127.0.0.1:6379> SETBIT k1 9 1 (integer) 0 127.0.0.1:6379> BITCOUNT k1 0 0 (integer) 2 127.0.0.1:6379> BITCOUNT k1 0 1 (integer) 3 ## 统计字节区间范围内的二进制总数
127.0.0.1:6379> BITCOUNT k1 0 -1 (integer) 3 127.0.0.1:6379> BITCOUNT k1 -2 -1
一年内某用户上线次数: 365为bit, 每天对应一个位,0,1表示上线。
127.0.0.1:6379> LPUSH l1 a (integer) 1 127.0.0.1:6379> LPUSH l1 b c d e f (integer) 6 127.0.0.1:6379> LRANGE l1 (error) ERR wrong number of arguments for 'lrange' command 127.0.0.1:6379> LRANGE l1 0 -1 1) "f" 2) "e" 3) "d" 4) "c" 5) "b" 6) "a" 127.0.0.1:6379> LPOP l1 "f" 127.0.0.1:6379> LPOP l1 "e" 127.0.0.1:6379> LPOP l1 "d" 127.0.0.1:6379> LPOP l1 "c" 127.0.0.1:6379> LPOP l1 "b" 127.0.0.1:6379> LPOP l1 "a" 127.0.0.1:6379> LPOP l1 (nil) 127.0.0.1:6379> LRANGE l1 0 -1 (empty list or set) 127.0.0.1:6379> LPUSH l1 b c d e f (integer) 5 127.0.0.1:6379> RPOP l1 "b" 127.0.0.1:6379> RPOP l1 "c" 127.0.0.1:6379> RPOP l1 "d" 127.0.0.1:6379> RPOP l1 "e" 127.0.0.1:6379> RPOP l1 "f" ## 从左到右,从上到下 [f e d c b] 127.0.0.1:6379> LPUSH l1 b c d e f (integer) 5 127.0.0.1:6379> LRANGE l1 1 1 1) "e" 127.0.0.1:6379> LRANGE l1 0 -1 1) "f" 2) "e" 3) "d" 4) "c" 5) "b" 127.0.0.1:6379> LRANGE l1 -2 -1 1) "c" 2) "b" 127.0.0.1:6379> LRANGE l1 -1 -2 (empty list or set) 127.0.0.1:6379> LPUSH l1 b c d e f (integer) 5 127.0.0.1:6379> RPOPLPUSH l1 l2 "b" 127.0.0.1:6379> LRANGE l2 0 -1 1) "b" 127.0.0.1:6379> LRANGE l1 0 -1 1) "f" 2) "e" 3) "d" 4) "c"
127.0.0.1:6379> LINDEX l1 2 "d" 127.0.0.1:6379> LLEN l1 (integer) 4 127.0.0.1:6379> RPUSH listkey c abc c ab 123 ab bj ab redis list (integer) 10 127.0.0.1:6379> LRANGE listkey 0 -1 1) "c" 2) "abc" 3) "c" 4) "ab" 5) "123" 6) "ab" 7) "bj" 8) "ab" 9) "redis" 10) "list" 127.0.0.1:6379> LREM listkey -1 ab (integer) 1 127.0.0.1:6379> LRANGE listkey 0 -1 1) "c" 2) "abc" 3) "c" 4) "ab" 5) "123" 6) "ab" 7) "bj" 8) "redis" 9) "list" 127.0.0.1:6379> LREM listkey 0 ab (integer) 2 127.0.0.1:6379> LRANGE listkey 0 -1 1) "c" 2) "abc" 3) "c" 4) "123" 5) "bj" 6) "redis" 7) "list" 127.0.0.1:6379> FLUSHALL OK 127.0.0.1:6379> RPUSH listkey c abc c ab 123 ab bj ab redis list (integer) 10 127.0.0.1:6379> help LTRIM LTRIM key start stop summary: Trim a list to the specified range since: 1.0.0 group: list 127.0.0.1:6379> LTRIM listkey 0 -1 OK 127.0.0.1:6379> LRANGE listkey 0 -1 1) "c" 2) "abc" 3) "c" 4) "ab" 5) "123" 6) "ab" 7) "bj" 8) "ab" 9) "redis" 10) "list" 127.0.0.1:6379> LTRIM listkey 0 0 OK 127.0.0.1:6379> LRANGE listkey 0 -1 ## 去除指定范围外的元素 1) "c" 127.0.0.1:6379> LPUSH l3 a b d (integer) 3 127.0.0.1:6379> LRANGE l3 0 -1 1) "d" 2) "b" 3) "a" 127.0.0.1:6379> LINSERT l3 before b x (integer) 4 127.0.0.1:6379> LRANGE l3 0 -1 1) "d" 2) "x" 3) "b" 4) "a"
windowA 127.0.0.1:6379> BLPOP l1 0 windowB 127.0.0.1:6379> BLPOP l1 0 windowC 127.0.0.1:6379> BLPOP l1 0 windowD 127.0.0.1:6379> LPUSH l1 1 windowA 127.0.0.1:6379> BLPOP l1 0 ## 阻塞中断 1) "l1" 2) "1" (92.45s) windowD 127.0.0.1:6379> LPUSH l1 1 windowB 127.0.0.1:6379> BLPOP l1 0 ## 阻塞中断 1) "l1" 2) "1" 127.0.0.1:6379> BLPOP l1 5 ## 5秒自动中断 (nil) (5.93s)
127.0.0.1:6379> FLUSHALL OK 127.0.0.1:6379> HSET mike name michael (integer) 1 127.0.0.1:6379> HSET mike age 30 (integer) 1 127.0.0.1:6379> HMSET mike gender m phone 13552594619 OK 127.0.0.1:6379> HVALS mike 1) "michael" 2) "30" 3) "m" 4) "13552594619" 127.0.0.1:6379> HKEYS mike 1) "name" 2) "age" 3) "gender" 4) "phone" 127.0.0.1:6379> set mike:name michael OK 127.0.0.1:6379> set mike:age 30 OK 127.0.0.1:6379> set mike:gender m OK 127.0.0.1:6379> keys * 1) "mike:age" 2) "mike:name" 3) "mike" 4) "mike:gender" 127.0.0.1:6379> HGET mike age "30" 127.0.0.1:6379> HGET mike name "michael" 127.0.0.1:6379> HLEN mike (integer) 4 127.0.0.1:6379> HGETALL mike 1) "name" 2) "michael" 3) "age" 4) "30" 5) "gender" 6) "m" 7) "phone" 8) "13552594619" 127.0.0.1:6379> HINCRBY mike age 10 (integer) 40 127.0.0.1:6379> HINCRBY mike age 10.5 (error) ERR value is not an integer or out of range 127.0.0.1:6379> HINCRBYFLOAT mike age 10.5 "50.5"
redis key分时点存储,到时点时去检查时间片下的数据是否过期。被动 当用户查询数据时,检查是否过期。 被动
127.0.0.1:6379> SADD s1 mike marie peter marry (integer) 4 127.0.0.1:6379> SMEMBERS s1 1) "peter" 2) "marie" 3) "mike" 4) "marry" 127.0.0.1:6379> SREM s1 peter (integer) 1 127.0.0.1:6379> SMEMBERS s1 1) "marie" 2) "mike" 3) "marry"
127.0.0.1:6379> SISMEMBER s1 peter (integer) 0 127.0.0.1:6379> SISMEMBER s1 marry (integer) 1
127.0.0.1:6379> SRANDMEMBER s1 "marry" 127.0.0.1:6379> SRANDMEMBER s1 "marie" 127.0.0.1:6379> SRANDMEMBER s1 1 1) "marry" 127.0.0.1:6379> SRANDMEMBER s1 2 1) "mike" 2) "marry" 127.0.0.1:6379> SRANDMEMBER s1 10 1) "mike" 2) "marie" 3) "marry" 127.0.0.1:6379> SRANDMEMBER s1 -100 ## 超过集合数量时,返回数量个。 1) "mike" 2) "marry" 3) "marry" 4) "marie" 5) "mike" 6) "marry" 7) "marry" ...100 127.0.0.1:6379> SRANDMEMBER s1 -2 1) "mike" 2) "marry" 127.0.0.1:6379> SPOP s1 "mike" 127.0.0.1:6379> SPOP s1 "marie" 127.0.0.1:6379> SCARD s1 (integer) 1
127.0.0.1:6379> FLUSHALL OK 127.0.0.1:6379> SADD number1 123 456 789 (integer) 3 127.0.0.1:6379> SADD number2 123 456 999 (integer) 3 127.0.0.1:6379> SDIFFSTORE number3 number1 number2 ## number1 去除1与2的交集 (integer) 1 127.0.0.1:6379> SMEMBERS number3 1) "789" 127.0.0.1:6379> SDIFFSTORE number4 number2 number1 (integer) 1 127.0.0.1:6379> SMEMBERS number4 1) "999" 127.0.0.1:6379> SUNION number5 number1 number2 1) "123" 2) "456" 3) "789" 4) "999" 127.0.0.1:6379> SINTER number1 number2 1) "123" 2) "456"
127.0.0.1:6379> ZADD fruits 3.2 香蕉 (integer) 1 127.0.0.1:6379> ZADD fruits 2.0 西瓜 (integer) 1 127.0.0.1:6379> ZADD fruits 4.0 番石榴 7.0 梨 6.8 芒果 (integer) 3 127.0.0.1:6379> ZRANGE fruits (error) ERR wrong number of arguments for 'zrange' command 127.0.0.1:6379> ZRANGE fruits (error) ERR wrong number of arguments for 'zrange' command 127.0.0.1:6379> ZRANGE fruits 0 -1 1) "\xe8\xa5\xbf\xe7\x93\x9c" 2) "\xe9\xa6\x99\xe8\x95\x89" 3) "\xe7\x95\xaa\xe7\x9f\xb3\xe6\xa6\xb4" 4) "\xe8\x8a\x92\xe6\x9e\x9c" 5) "\xe6\xa2\xa8" 127.0.0.1:6379> quit [root@node1 ~]# redis-cli --raw 127.0.0.1:6379> ZRANGE fruits 0 -1 西瓜 香蕉 番石榴 芒果 梨 127.0.0.1:6379> ZRANGE fruits 0 -1 withscores 西瓜 2 香蕉 3.2000000000000002 番石榴 4 芒果 6.7999999999999998 梨 7
127.0.0.1:6379> ZREVRANGE fruits 0 -1 withscores 梨 7 芒果 6.7999999999999998 番石榴 4 香蕉 3.2000000000000002 西瓜 2 127.0.0.1:6379> ZRANGE fruits -3 -1 番石榴 芒果 梨 127.0.0.1:6379> ZRANGE fruits -3 -1 withscores 番石榴 4 芒果 6.7999999999999998 梨 7
127.0.0.1:6379> ZSCORE fruits 芒果 6.7999999999999998 127.0.0.1:6379> ZINCRBY fruits 1.5 芒果 8.3000000000000007 127.0.0.1:6379> ZRANGE fruits 0 -1 西瓜 香蕉 番石榴 梨 芒果 127.0.0.1:6379> ZRANK fruits 西瓜 0 127.0.0.1:6379> ZRANK fruits 西瓜 0 127.0.0.1:6379> ZREVRANK fruits 番石榴 2 127.0.0.1:6379> ZREVRANK fruits 芒果 0 127.0.0.1:6379> ZRANGE fruits 3 4 withscores 梨 7 芒果 8.3000000000000007 127.0.0.1:6379> ZRANGEBYSCORE fruits 3 3.5 withscores 香蕉 3.2000000000000002 127.0.0.1:6379> ZRANGEBYSCORE fruits (3.2 3.5 withscores 127.0.0.1:6379> ZRANGEBYSCORE fruits -inf +inf withscores 西瓜 2 香蕉 3.2000000000000002 番石榴 4 梨 7 芒果 8.3000000000000007 127.0.0.1:6379> ZREMRANGEBYRANK fruits 0 0 1 127.0.0.1:6379> ZRANGEBYSCORE fruits -inf +inf withscores 香蕉 3.2000000000000002 番石榴 4 梨 7 芒果 8.3000000000000007 127.0.0.1:6379> ZCARD fruits ## 返回元素个数 4 127.0.0.1:6379> ZCOUNT fruits 4 7 ## 分值范围内元素的个数 2 127.0.0.1:6379> ZCOUNT fruits 5 7 1
举例 ZADD scores1 70 tom 80 peter 60 john ZADD scores2 90 peter 60 ben ZUNIONSTORE scores-all 2 scores1 scores2 ZUNIONSTORE scores-all1 2 scores1 scores2 AGGREGATE SUM ZUNIONSTORE scores-all2 2 scores1 scores2 WEIGHTS 1 0.5
127.0.0.1:6379> ZADD scores1 70 tom 80 peter 60 john 3 127.0.0.1:6379> ZADD scores2 90 peter 60 ben 2 127.0.0.1:6379> ZUNIONSTORE scores3 2 scores1 scores2 4 127.0.0.1:6379> ZRANGE scores3 0 -1 withscores ben 60 john 60 tom 70 peter 170 127.0.0.1:6379> ZUNIONSTORE scores-all1 2 scores1 scores2 AGGREGATE SUM 4 127.0.0.1:6379> ZRANGE scores-all1 0 -1 withscores ben 60 john 60 tom 70 peter 170 127.0.0.1:6379> ZUNIONSTORE scores-all2 2 scores1 scores2 WEIGHTS 1 0.5 AGGREGATE SUM 4 127.0.0.1:6379> ZRANGE scores-all2 0 -1 withscores ben 30 john 60 tom 70 peter 125
mysql索引 btree https://www.jianshu.com/p/0371c9569736 跳跃表 https://blog.csdn.net/qpzkobe/article/details/80056807
AOF开启之后,RDB就不会被采纳。
数据承载的方式: 集群 分片 3台4G内存,最多承载12G数据,每一台4G,只是缺少备份 lvs 镜像全量 3台4G内存, 一模一样的机器和数据,最多承载4G
CAP原则 https://baike.baidu.com/item/CAP%E5%8E%9F%E5%88%99/5712863?fr=aladdin 无主模型 主从模型
sentinel 英 ['sentɪn(ə)l] 美 ['sɛntɪnl] n. 哨兵 vt. 守卫,放哨
https://www.jianshu.com/p/d9d067a8a086 paxos 论文: 分布式系统一致性的基本理论
官网,和java client源码 https://redis.io/clients https://github.com/xetorthio/jedis
伪分布式搭建 node1上 [root@node1 ~]# mkdir redis [root@node1 redis]# mkdir 6380 [root@node1 redis]# mkdir 6381 [root@node1 redis]# mkdir 6382 [root@node1 redis]# cd 6380/ [root@node1 6380]# redis-server -h [root@node1 6380]# redis-server -port 6380 ## 默认异master身份启动 [root@node1 6381]# pwd /root/redis/6381 [root@node1 6381]# redis-server --port 6381 --slaveof 127.0.0.1 6380 ## 启动slave [root@node1 6382]# redis-server --port 6382 --slaveof 127.0.0.1 6380 [root@node1 ~]# redis-cli -p 6380 127.0.0.1:6380> set k1 5 OK 127.0.0.1:6380> get k1 "5" [root@node1 ~]# redis-cli -p 6381 127.0.0.1:6381> get k1 "5" [root@node1 ~]# redis-cli -p 6382 127.0.0.1:6382> get k1 "5" 127.0.0.1:6382> set k3 dsfsd ## slave 只能读,不能写,master才能够写入 (error) READONLY You can't write against a read only slave. ## 当6380 ctrl+c挂掉之后。
127.0.0.1:6381> SLAVEOF no one ## 6381手动成为master 127.0.0.1:6381> set k3 dfsd OK [root@node1 6380]# redis-server --port 6380 --slaveof 127.0.0.1 6381 ## 启动6380称为81的slave not connected> get k3 "dfsd" 127.0.0.1:6380> set k4 werwe (error) READONLY You can't write against a read only slave. ## 如上手动切换比较麻烦。
哨兵,单独存在的。
配置和启动 [root@node1 src]# cp redis-sentinel /opt/sxt/redis/bin [root@node1 src]# ls /opt/sxt/redis/bin/ redis-benchmark redis-check-aof redis-check-dump redis-cli redis-sentinel redis-server [root@node1 src]# cd [root@node1 ~]# mkdir sent [root@node1 ~]# cd sent/ [root@node1 sent]# vi s1.conf [root@node1 sent]# cp s1.conf s2.conf [root@node1 sent]# cp s1.conf s3.conf [root@node1 sent]# vi s2.conf [root@node1 sent]# vi s3.conf [root@node1 sent]# cat s*.conf port 23680 sentinel monitor sxt 127.0.0.1 6380 2 port 23681 sentinel monitor sxt 127.0.0.1 6380 2 port 23682 sentinel monitor sxt 127.0.0.1 6380 2 [root@node1 6380]# redis-server --port 6380 [root@node1 6381]# redis-server --port 6381 --slaveof 127.0.0.1 6380 [root@node1 6382]# redis-server --port 6382 --slaveof 127.0.0.1 6380 [root@node1 sent]# redis-sentinel s1.conf ## ~/sent ## 启动哨兵 [root@node1 sent]# redis-sentinel s2.conf [root@node1 sent]# redis-sentinel s3.conf ## ctrl+c结束6380服务。 ## 稍等一会,哨兵自动选举, s2,s3下的日志 [10204] 14 Sep 14:33:28.946 # +switch-master sxt 127.0.0.1 6380 127.0.0.1 6382 ## 此时6382称为主 ## 重新启动6380,以master身份。 [root@node1 6380]# redis-server --port 6380 ## 此时6382还是master,6380是slave.
Redis3.0提供了集群解决方案
slot 英 [slɒt] 美 [slɑt] n. 位置;狭槽;水沟;硬币投币口 vt. 跟踪;开槽于
3.0的节点既是节点又是哨兵的功能。 redis集群环境搭建 [root@node1 redis-cluster]# pwd /root/software/redis-cluster [root@node1 redis-cluster]# ll total 1432 -rw-r--r--. 1 root root 1364993 Jun 4 2018 redis-3.0.4.tar.gz -rw-r--r--. 1 root root 92160 Jun 4 2018 redis-3.3.0.gem ## 依赖ruby环境 drwxr-xr-x. 8 root root 4096 Sep 14 15:25 redis-test [root@node1 redis-cluster]# tar xf redis-3.0.4.tar.gz [root@node1 redis-cluster]# cd redis-3.0.4 [root@node1 redis-3.0.4]# whereis gcc tcl [root@node1 redis-3.0.4]# make && make PREFIX=/opt/sxt/redis/ install [root@node1 redis-3.0.4]# cd /opt/sxt/redis/ [root@node1 redis]# ls bin [root@node1 redis]# cd bin/ [root@node1 bin]# ll total 8520 -rwxr-xr-x. 1 root root 2077192 Sep 14 15:29 redis-benchmark -rwxr-xr-x. 1 root root 25104 Sep 14 15:29 redis-check-aof -rwxr-xr-x. 1 root root 55936 Sep 14 15:29 redis-check-dump -rwxr-xr-x. 1 root root 2201240 Sep 14 15:29 redis-cli lrwxrwxrwx. 1 root root 12 Sep 14 15:29 redis-sentinel -> redis-server -rwxr-xr-x. 1 root root 4352016 Sep 14 15:29 redis-server [root@node1 bin]# cd ~/software/redis-cluster/ [root@node1 redis-cluster]# ls redis-3.0.4 redis-3.0.4.tar.gz redis-3.3.0.gem redis-test [root@node1 redis-cluster]# yum -y install ruby rubygems ## 安装ruby环境 [root@node1 redis-cluster]# ls redis-3.0.4 redis-3.0.4.tar.gz redis-3.3.0.gem redis-test [root@node1 redis-cluster]# gem install --local redis-3.3.0.gem ## 本地安装gem(redis依赖ruby组件) [root@node1 redis-cluster]# cd redis-test/ [root@node1 redis-test]# ls 7000 7001 7002 7003 7004 7005 [root@node1 redis-test]# cd 7000/ -rw-r--r--. 1 root root 30 Jun 4 2018 redis.conf [root@node1 7000]# cat redis.conf ## 每个文件加下的配置对应700x cluster-enabled yes port 7000 ###通过单节点演示6个实例;node1 打开6个终端 进入各个700x文件夹 [root@node1 7000]# pwd /root/software/redis-cluster/redis-test/7000 ## 6个终端都启动实例 执行 redis-server r* [root@node1 7000]# redis-server r* ## 相当于6个无主的实例 ##指定集群 前三个是主,后三个是备 [root@node1 src]# ./redis-trib.rb create --replicas 1 127.0.0.1:7000 127.0.0.1:7001 \ > 127.0.0.1:7002 127.0.0.1:7003 127.0.0.1:7004 127.0.0.1:7005 [root@node1 src]# redis-cli -p 7000 ## 错误 应该-c 127.0.0.1:7000> set k1 5 (error) MOVED 12706 127.0.0.1:7002 127.0.0.1:7000> [root@node1 src]# redis-cli -p 7000 -c ## -c以集群方式进入 127.0.0.1:7000> set k1 5 -> Redirected to slot [12706] located at 127.0.0.1:7002 ## 槽位和数据 OK 127.0.0.1:7002> set k2 10 -> Redirected to slot [449] located at 127.0.0.1:7000 OK 127.0.0.1:7000> get k2 "10" 127.0.0.1:7000> get k1 -> Redirected to slot [12706] located at 127.0.0.1:7002 "5" [root@node1 ~]# redis-cli -p 7000 -c 127.0.0.1:7000> get k1 -> Redirected to slot [12706] located at 127.0.0.1:7002 "5" 127.0.0.1:7002> exit [root@node1 ~]# redis-cli -p 7003 -c 127.0.0.1:7003> get k1 -> Redirected to slot [12706] located at 127.0.0.1:7002 "5" 127.0.0.1:7002> exit ## 将7000 ctrl+c结束, 此时,7003备接替。get k1时,不会重定向 [root@node1 ~]# redis-cli -p 7003 -c 127.0.0.1:7003> get k2 "10"
redis-shake进展: 请选择版本号为:redis-6.2 redis-shake-v2.1 实验同步成功; 1.架构 注意版本问题:我本地用的是5.0.14版本 redis-cluster-A 7000 7001 7002 是master 7003 7004 7005是slave redis-cluster-B 7000 7001 7002 是master 7003 7004 7005是slave redis-shake 2.安装 redis安装步骤: https://redis.io/docs/getting-started/installation/install-redis-from-source/ https://blog.csdn.net/dingxiaoyao1985/article/details/124019087 https://www.redis.com.cn/topics/cluster-tutorial.html wget https://download.redis.io/redis-stable.tar.gz tar -xzvf redis-stable.tar.gz cd redis-stable make 如果报错,请执行如下命令: sudo apt-get install -y make sudo apt-get install -y pkg-config apt-get install -y gcc automake autoconf libtool make distclean make install PREFIX=/home/test/redistest/redis mkdir cluster test@ubuntu20:~/redistest/cluster$ pwd /home/test/redistest/cluster cd cluster/ mkdir 7000 7001 7002 7003 7004 7005 vim 7000/redis.conf cluster-enable yes port 7000 cp 7000/redis.conf ./7001/ sed -i 's/8000/8001/g' 8001/redis.conf ../redis-server redis.conf ../../bin/redis-server ./redis.conf test@ubuntu20:~/redistest/redis/cluster/7005$ pwd /home/test/redistest/redis/cluster/7005 (需要到当前目录下执行,生产的nodes.conf,appendonlydir文件才不会被相互覆盖) test@ubuntu20:~/redistest/redis/cluster/7005$ cat redis.conf port 7005 cluster-enabled yes cluster-config-file nodes.conf cluster-node-timeout 5000 appendonly yes daemonize yes # redis后台运行 启动服务: test@ubuntu20:~/redistest/redis/cluster/7005$ ../../bin/redis-server ./redis.conf & scp -r redis test@192.168.79.151:/home/test/redistest 创建集群 Redis5通过redis-cli就可以创建集群;Redis3或4需要使用redis集群的命令工具redis-trib。 redis-cli --cluster create 127.0.0.1:7000 127.0.0.1:7001 127.0.0.1:7002 \ 127.0.0.1:7003 127.0.0.1:7004 127.0.0.1:7005 --cluster-replicas 1 登录节点 -c 连接集群结点时使用 ./bin/redis-cli -c -p 7000 查看:集群状态 https://blog.csdn.net/m0_67390969/article/details/124121711 redis-cli -h ip -p 9379 -a password cluster info redis-cli -p 7000 cluster info redis-cli -p 7005 info redis-cli -p 7005 cluster nodes
https://help.aliyun.com/document_detail/125941.html?spm=a2c4g.11186623.6.628.c1c94ddcX5gbCE
同步数据: vim redis-shake.conf source.type = cluster source.address = 192.168.79.152:7003;192.168.79.152:7004;192.168.79.152:7005 target.type = cluster target.address = 192.168.79.151:7000;192.168.79.151:7001;192.168.79.151:7002 rewrite = true ./redis-shake -type=sync -conf=redis-shake.conf ./redis-shake.linux -type=sync -conf=redis-shake.conf 其他帮助命令 杀死所有redis进程 for i in `ps -ef|grep redis |awk '{print $2}' `; do kill -9 $i ; done;
https://help.aliyun.com/document_detail/125941.html?spm=a2c4g.11186623.6.628.c1c94ddcX5gbCE
https://help.aliyun.com/document_detail/111066.html?spm=a2c4g.11186623.6.625.52597ce0BQ1GwU
redis版本 |
redis-shake版本 |
是否报错 |
是否同步成功 |
redis-6.2.7 |
redis-shake-v2.1.2 |
无 |
成功 |
redis-7.0.0 |
redis-shake-v2.1.2 |
有[invalid RDB version number 10, 9] |
失败 |
redis-5.0.14 |
redis-shake-v2.1.2, redis-shake-v2.0.3 |
无 |
失败(查询不到同步数据) |