一、redis简介
1、nosql简介
- NoSQL泛指非关系型的数据库,是不同于传统的关系数据库的数据库管理系统的统称。其两者最重要的区别是NoSQL不使用SQL作为查询语言。
- NoSQL数据存储可以不需要固定的表格模式。NoSQL是基于键值对的,可以想象成表中的主键和值的对应关系。
- 常用NoSQL:redis、memcached、mongodb、guava(loadingCache)
2、redis简介
Redis是一个用C语言编写的开源的高性能key-value分布式内存数据结构存储系统并支持持久化的nosql数据库。它可以用作数据库、缓存和消息中间件。 它支持多种类型的数据结构,如字符串(strings)、散列(hashes)、列表(list)、集合(sets)、有序集合 (sorted set)等。
3、redis特点
- Redis支持数据的持久化,可以将内存中的数据保持在磁盘中,重启的时候可以再次加载进行使用
- Redis不仅仅支持简单的key-value类型的数据,同时还提供list,set,zset,hash等数据结构的存储
- Redis支持数据的备份,即master-slave模式的数据备份
二、linux下安装redis
下载地址1:redis.io/download
下载地址2:www.redis.cn/download.ht…
1、命令行下载并安装
$ wget http://download.redis.io/releases/redis-5.0.5.tar.gz
$ tar -zxvf redis-5.0.5.tar.gz -C /usr/local/
$ cd redis-5.0.5
$ make
$ make install
2、如果make安装失败,则提示缺少gcc环境
$ yum install gcc-c++
$ make distclean
$ make
$ make install
3、启动客户端
# 启动服务端
$ ./src/redis-server
# 启动服务端并指定配置文件
$ ./src/redis-server ./redis.conf
4、验证启动是否成功
$ ps ‐ef | grep redis
5、启动客户端
# 启动客户端
$ ./src/redis-cli
# 启动客户端并指定端口号
$ ./src/redis-cli -p 6379
6、退出客户端
$ quit
7、退出redis服务
$ kill -9 进程号
三、redis核心数据结构
redis提供五种数据类型:string、hash、list、set、zset(sorted set)
1、string数据类型
- String类型是redis最基本的数据类型,一个key对应一个value
- String类型是二进制安全的,redis的String可以包含任何数据,比如jpg图片或者序列化的对象
- String类型是redis最基本的数据类型,一个redis中字符串value最多可以是512M
string常用操作:
set key value:存入字符串key对应的value值
mset key1 value1 key2 value2 ...:批量存入字符串key对应的value值
setnx key value:当字符串key不存在时才存入其对应的值
get key:获取字符串key对应的值
mget key1 key2 ...:批量获取字符串key对应的值
del key1 key2 ...:批量删除字符串key对应的值
expire key seconds:设置字符串key对应的值的过期时间(秒)
原子加减:
incr key:将key中储存的数字值加1
decr key:将key中储存的数字值减1
incrby key increment:将key中储存的数字值加increment
decrby key decrement:将key中储存的数字值减increment
应用场景:
- 单值缓存
- 对象缓存
- 分布式锁
- 计数器
- web集群session共享
- 分布式系统全局序列号
二、hash数据类型
- Hash是一个键值对集合
- Hash是一个String类型的field和value的映射表,Hash特别适合于存储对象
- 类似于java里面的Map<String,Object>
hash常用操作:
hset key field value:设置hash的key对应的field字段和value值
hsetnx key field value:hash的key对应的field字段不存在才设置value值
hget key field:获取hash的key对应的field字段的值
hmset key field1 value1 field2 value2 ...:批量设置hash的key对应的field字段和value值
hmget key field1 field2 ...:批量获取hash的key对应的field字段的值
hdel key field1 field2 ...:批量删除hash的key对应的field字段的值
hlen key:返回hash的key中字段的数量
hgetall key:返回hash的key中所有的字段和字段值
hincrby key field increment:给hash的key中的field字段对应的值加上增量increment
应用场景:
- 对象缓存
- 电商购物车
3、list常用操作
- redis列表是最简单的字符串列表,按照插入顺序排序,可以添加一个元素到列表的头部(左边)或者尾部(右边),它的底层实际是个链表,可以包含重复的元素
list常用操作:
lpush key value1 value2 ...:从列表key的左端插入一个或多个值
rpush key value1 value2 ...:从列表key的右端插入一个或多个值
lpop key:从列表key左侧弹出一个值
rpop key:从列表key右侧弹出一个值
lrange key start stop:遍历列表key左侧指定区间内的元素
blpop key1 key2 ... timeout:从列表key表头弹出一个元素,若列表中没有元素,阻塞等待timeout秒,如果timeout=0,则会一直阻塞等待
brpop key1 key2 ... timeout:从列表key表尾弹出一个元素,若列表中没有元素,阻塞等待timeout秒,如果timeout=0,则会一直阻塞等待
常用数据结构:
Stack(栈) = LPUSH + LPOP(First In Last Out)
Queue(队列) = LPUSH + RPOP
Blocking MQ(阻塞队列) = LPUSH + BRPOP
应用场景:
- 微博和微信消息流
4、set数据类型
- redis的Set是String类型的无序集合,它是通过HashTable来实现的
set常用操作:
sadd key member1 member2 ...:向集合key中存入member元素
srem key member1 member2 ...:从集合key中删除元素member元素
smembers key:获取集合key中的所有元素
scard key:获取有序集合key中元素的数量
sismember key member:判断member元素是否在集合key中
srandmember key count:从集合key中选出count个元素,元素不从key中删除
spop key count:从集合key中选出count个元素,元素从key中删除
set运算操作:
sinter key1 key2 ...:交集运算
sinterstore destination key1 key2 ...:将交集结果存入新集合destination中
sunion key1 key2 ...:并集运算
sunionstore destination key1 key2 ...:将并集结果存入新集合destination中
sdiff key1 key2 ...:差集运算
sdiffstore destination key1 key2 ...:将差集结果存入新集合destination中
应用场景:
- 微信抽奖小程序
- 微信微博点赞、收藏、标签
- 集合操作实现微博微信关注模型
- 集合操作实现电商商品筛选
5、zset(sorted set)数据类型
- zset是set的一个升级版本,和Set一样也是String类型元素的集合,且不允许有重复的元素
- 不同的是每个元素都会关联一个double类型的分数
- redis正是通过分数来为集合中的成员进行从小到大的排序,Zset的成员是唯一的,但分数(score)却可以重复
zset常用操作:
zadd key score1 member1 score2 member2 ...:向有序集合key中加入一个带score分数值的member元素
zrem key member1 member2 ...:从有序集合key中删除member元素
zscore key member:获取有序集合key中元素member的分数值
zincrby key increment member:增加有序集合key中member元素的分数值(增加的分数值大小为increment)
zcard key:获取有序集合key中元素的数量
zrange key start stop:正序获取有序集合key中从start下表到stop下标的元素
zrevrange key start stop:倒序获取有序集合key中从start下表到stop下标的元素
zset集合操作:
zunionstore destination numkeys key1 key2 ...:并集计算
zinterstore destination numkeys key1 key2:交集计算
应用场景:
- zset集合操作实现排行榜
6、redis更多应用场景
- 微博、微信、默默<附近的人>
- 微信<摇一摇><抢红包>
- 滴滴打车、摩拜单车<附近的车>
- 美团和饿了么<附近的餐馆>
- 搜索自动补全
- 布隆过滤器
- ... ...
四、redis核心原理
1、redis的单线程和高性能
redis单线程为什么还能这么快?
因为它所有的数据都在内存中,所有的运算都是内存级别的运算,而且单线程避免了多线程的切换性能损耗问题。正因为Redis是单线程,所以要小心使用Redis指令,对于那些耗时的指令(比如keys *),一定要谨慎使用,一不小心就可能会导致Redis卡顿。
redis单线程如何处理那么多的并发客户端连接?
Redis的IO是多路复用的,redis利用epoll来实现IO多路复用,将连接信息和事件放到队列中,依次放到 文件事件分派器,事件分派器将事件分发给事件处理器
查看redis支持的最大连接数,在redis.conf文件中可修改,默认配置如下:
# maxclients 10000
2、其他高级命令
keys全量遍历键:
用来列出所有满足特定正则字符串规则的key,当redis数据量比较大时,性能比较差,要避免使用
scan渐进式遍历键:
scan cursor match pattern count count]
scan命令提供了三个参数,第一个是cursor(整数值),第二个是key的正则模式,第三个是一次遍历的key的数量,并不是符合条件的结果数量。第一次遍历时,cursor值为0,然后将返回结果中第一个整数值作为下一次遍历的cursor,一直遍历到返回的cursor值为0时结束。
info:查看redis服务运行信息
分为9大块,每个块都有非常多的参数,这9个块分别是:
- Server 服务器运行的环境参数
- Clients 客户端相关信息
- Memory 服务器运行内存统计数据
- Persistence 持久化信息
- Stats 通用统计数据
- Replication 主从复制相关信息
- CPU CPU 使用情况
- Cluster 集群信息
- KeySpace 键值对统计数量信息
127.0.0.1:6379> info
# Server
redis_version:5.0.6
redis_git_sha1:00000000
redis_git_dirty:0
redis_build_id:5ecb0246e42149d4
redis_mode:standalone
os:Linux 3.10.0-957.27.2.el7.x86_64 x86_64
arch_bits:64
multiplexing_api:epoll
atomicvar_api:atomic-builtin
gcc_version:4.8.5
process_id:1974
run_id:763e43b749326a3ced814f36c0a847df8ab85370
tcp_port:6379
uptime_in_seconds:125801
uptime_in_days:1
hz:10
configured_hz:10
lru_clock:13884734
executable:/usr/local/redis-5.0.6/./src/redis-server
config_file:
# Clients
connected_clients:1
client_recent_max_input_buffer:2
client_recent_max_output_buffer:0
blocked_clients:0
# Memory
used_memory:854632
used_memory_human:834.60K
used_memory_rss:3821568
used_memory_rss_human:3.64M
used_memory_peak:4957272
used_memory_peak_human:4.73M
used_memory_peak_perc:17.24%
used_memory_overhead:842310
used_memory_startup:792312
used_memory_dataset:12322
used_memory_dataset_perc:19.77%
allocator_allocated:1258048
allocator_active:1507328
allocator_resident:7380992
total_system_memory:4142325760
total_system_memory_human:3.86G
used_memory_lua:37888
used_memory_lua_human:37.00K
used_memory_scripts:0
used_memory_scripts_human:0B
number_of_cached_scripts:0
maxmemory:0
maxmemory_human:0B
maxmemory_policy:noeviction
allocator_frag_ratio:1.20
allocator_frag_bytes:249280
allocator_rss_ratio:4.90
allocator_rss_bytes:5873664
rss_overhead_ratio:0.52
rss_overhead_bytes:-3559424
mem_fragmentation_ratio:4.70
mem_fragmentation_bytes:3008896
mem_not_counted_for_evict:0
mem_replication_backlog:0
mem_clients_slaves:0
mem_clients_normal:49694
mem_aof_buffer:0
mem_allocator:jemalloc-5.1.0
active_defrag_running:0
lazyfree_pending_objects:0
# Persistence
loading:0
rdb_changes_since_last_save:0
rdb_bgsave_in_progress:0
rdb_last_save_time:1574165776
rdb_last_bgsave_status:ok
rdb_last_bgsave_time_sec:0
rdb_current_bgsave_time_sec:-1
rdb_last_cow_size:151552
aof_enabled:0
aof_rewrite_in_progress:0
aof_rewrite_scheduled:0
aof_last_rewrite_time_sec:-1
aof_current_rewrite_time_sec:-1
aof_last_bgrewrite_status:ok
aof_last_write_status:ok
aof_last_cow_size:0
# Stats
total_connections_received:7
total_commands_processed:166
instantaneous_ops_per_sec:0
total_net_input_bytes:7635
total_net_output_bytes:84380
instantaneous_input_kbps:0.00
instantaneous_output_kbps:0.00
rejected_connections:54
sync_full:0
sync_partial_ok:0
sync_partial_err:0
expired_keys:2
expired_stale_perc:0.00
expired_time_cap_reached_count:0
evicted_keys:0
keyspace_hits:43
keyspace_misses:5
pubsub_channels:0
pubsub_patterns:0
latest_fork_usec:339
migrate_cached_sockets:0
slave_expires_tracked_keys:0
active_defrag_hits:0
active_defrag_misses:0
active_defrag_key_hits:0
active_defrag_key_misses:0
# Replication
role:master
connected_slaves:0
master_replid:4df5e4af04a0670996de7170b1387111487b0899
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:0
second_repl_offset:-1
repl_backlog_active:0
repl_backlog_size:1048576
repl_backlog_first_byte_offset:0
repl_backlog_histlen:0
# CPU
used_cpu_sys:80.226871
used_cpu_user:114.513057
used_cpu_sys_children:0.008760
used_cpu_user_children:0.007374
# Cluster
cluster_enabled:0
# Keyspace
db0:keys=6,expires=0,avg_ttl=0