在启动 redis-server 进程后,启动redis-client 进程便可以操作了。在终端属于命令可以完成增删改查等操作,同时 Redis 还提供了 API,
一、启动 redis server 和 redis client
在安装 redis 时可以将 ${redis_home}/src 路径
(其中包含 redis-server 和 redis-cli 文件)配置到环境变量 PATH
中,这样的话就可以直接在终端 terminal 中输入命令即可启动redis server 和 redis client,比如:
# redis home
export PATH="/usr/local/redis-5.0.5/src:$PATH"
1.1 先启动 redis server
在 终端 terminal 中输入redis-server
命令(也可添加参数,-h 表示host,-p 表示端口):
redis-server
# 或者 redis-server -h 127.0.0.1 -p 6379
这里需要注意的是
:如果 redis 的配置项daemonize
被设置为 true
(在redis.conf 中设置的,默认为false),那么 redis server 将会以守护进程的方式运行在后台,那么当前 terminal 是可以 close 的。如果daemonize
为 false
时 ,一旦当前 terminal 被 close,redis-server 进程就会退出。
# daemonize为 false 时
......
44254:M 15 Nov 2019 10:28:01.492 * Increased maximum number of open files to 10032 (it was originally set to 256).
_._
_.-``__ ''-._
_.-`` `. `_. ''-._ Redis 5.0.5 (00000000/0) 64 bit
.-`` .-```. ```\/ _.,_ ''-._
( ' , .-` | `, ) Running in standalone mode
|`-._`-...-` __...-.``-._|'` _.-'| Port: 6379
| `-._ `._ / _.-' | PID: 44254
`-._ `-._ `-./ _.-' _.-'
|`-._`-._ `-.__.-' _.-'_.-'|
| `-._`-._ _.-'_.-' | http://redis.io
`-._ `-._`-.__.-'_.-' _.-'
|`-._`-._ `-.__.-' _.-'_.-'|
| `-._`-._ _.-'_.-' |
`-._ `-._`-.__.-'_.-' _.-'
`-._ `-.__.-' _.-'
`-._ _.-'
`-.__.-'
44254:M 15 Nov 2019 10:28:01.500 # Server initialized
44254:M 15 Nov 2019 10:28:01.500 * Ready to accept connections
1.2 然后启动 redis client
redis-cli
# 或者防止中文乱码 redis-cli --raw
启动后:
127.0.0.1:6379>
输入 ping
(大小写无所谓)如果打印出 PONG
,说明 redis client 成功启动:
127.0.0.1:6379> ping
PONG
127.0.0.1:6379>
注意:
- 客户端向 Redis 服务器发送一个 PING ,如果服务器运作正常的话,会返回一个 PONG 。通常用于测试与服务器的连接是否仍然生效,或者用于测量延迟值;
- 如果 redis-cli 在做查询等操作时报如下错误,那是因为 redis-server
设置了密码访问(redis.conf 中添加了配置项 requirepass)
,关于 Redis 配置密码访问可以参考博客:https://www.jianshu.com/p/4d3ec8ba8828。
127.0.0.1:6379> keys *
(error) NOAUTH Authentication required.
二、修改配置项
Redis home 目录下存在一个文件 redis.conf,是 redis 的配置文件,比如上面说的 daemonize 就是其中一个重要的配置项。这些配置项都有自己的默认值,要修改这些配置项的值有两种途径:
- 直接
修改 redis.conf 文件
,全局生效
; - 在某个
client 端使用 config set 命令修改
,只在当前 client 中生效
,但是只能修改部分配置项
,比如 daemonize 就不能在 client 端被修改;
命令形式:
config set 配置项名称 取值
# 在 client 端修改配置项 loglevel 的值
127.0.0.1:6379> config set loglevel warning
OK
127.0.0.1:6379> get loglevel
(nil)
127.0.0.1:6379> config get loglevel
1) "loglevel"
2) "warning"
127.0.0.1:6379>
# 其中第一个是key,第二个是value
注意:
一般情况下redis server 启动时会加载Redis home 目录下的 redis.conf。但是也可以在启动 redis server 时指定其加载自定义的其他路径中的 redis.conf:
redis-server /path/to/redis.conf
三、数据增删查改操作
3.1 Redis 支持的数据类型
首先,无疑所有的 key 都是 String 类型,但是对应的 Value 则有如下数据类型:
- String:Redis 中最常见的类型,Redis 中的 String 是
二进制安全的
,也就是说还能够存储图片或序列化的东西,存储上限512MB
;关于String 二进制安全
可以参考博客https://blog.csdn.net/wuliecho/article/details/72770437; - Hash:即HashMap Set,存储
key-value pair 集合
,常用于存储对象; - List:列表,其中的元素是String,按照插入顺序排序;
- Set:集合,其中的元素是String,无重复元素;
- SortedSet:本质上是HashMap,无重复元素,按照 key 排序。
附:String 二进制安全就是输入任何字节都能正确处理, 即使包含零值字节.
3.2 操作命令
注意:
- 如果命令记不清,可以在 Redis shell 中
按 tab 键提示
,比如关于 HashMap 操作,我只记得命令是以 H 开头,那么就可以先输入 H 再按tab 键即可; - 如果不知道某个命令的用途可以使用
help <命令名称>
即可,比如:
127.0.0.1:6379> help HKEYS
HKEYS key
summary: Get all the fields in a hash
since: 2.0.0
group: hash
- 查看 Redis server 的版本:
$ redis-server --version
Redis server v=5.0.6 sha=00000000:0 malloc=libc bits=64 build=25f7d67ca5603fd3
接下来是 Redis shell 常用命令汇总表:
添加、更新操作 | 命令 | 示例 | 备注 |
---|---|---|---|
添加key-value对 或 更新指定key的value:String
|
set key_name value | set name zhang | 无 |
添加key-value对 或 更新指定key的value:HashMap
|
hmset | hmset map1 id 1 name zhang age 88 | 获取HashMap中某个key的值:hget map1 name。其中 id、name、age都是 key |
添加key-value对 或 更新指定key的value:List
|
lpush | lpush list1 mongodb | 从左侧向右push一个元素进入list1,比如 list1 原来只有1个元素 redis,该操作后就有2个元素mongodb、redis |
添加key-value对 或 更新指定key的value:List
|
rpush | rpush list1 oracle | 从右侧向左push一个元素进入list1,该操作后就有3个元素mongodb、redis、oracle |
添加key-value对 或 更新指定key的value: List
|
linsert | linsert list1 after mongodb sqlserver | 从左侧向右insert一个元素 sqlserver 进入 list1,该元素放置在元素 mongodb 的后面(从左向右逐个比对,一旦发现就执行),该操作后就有4个元素mongodb、sqlserver、redis、oracle |
添加key-value对 或 更新指定key的value:List
|
linsert | linsert list1 before mongodb sqlserver | 从左侧向右insert一个元素 sqlserver 进入 list1,该元素放置在元素 mongodb 的前面(从左向右逐个比对,一旦发现就执行),该操作后就有5个元素sqlserver、mongodb、sqlserver、redis、oracle |
更新指定偏移量的元素:List
|
lset | lset list1 0 mysql | 将 list1 中的首个元素更新为 mysql |
添加key-value对 或 更新指定key的value: Set
|
sadd | sadd set1 a | 将元素 a 添加到 set1 中 |
添加key-value对 或 更新指定key的value: Sorted Set
|
zadd | zadd sset1 1 a | 将元素 a 添加到 sset1 中 |
获取操作 | 命令 | 示例 | 备注 |
---|---|---|---|
获取 String | get | get name | 返回 "zhang" |
获取整个 HashMap(包括 key 和 value) | hgetall | hgetall map1 | 返回 "id" "1" "name" "zhang" "age" "88" |
获取 HashMap 中某个 key 的 value | hget | hget map1 name | 返回 "zhang" |
获取 HashMap 中所有的 key | hkeys | hkeys map1 | 返回 "id" "name" "age" |
获取 HashMap 中所有的 value | hvals | hvals map1 | 返回 "1" "zhang" "88" |
获取整个 Set | sgetall | hgetall map1 | 返回 "id" "1" "name" "zhang" "age" "88" |
获取 Set 中所有元素 | smembers | smembers set1 | 比如返回 "a" |
获取 HashMap 中所有的 key | hkeys | hkeys map1 | 返回 "id" "name" "age" |
获取 HashMap 中所有的 value | hvals | hvals map1 | 返回 "1" "zhang" "88" |
根据偏移量 index 获取 List 中的某个元素 | lindex | lindex list1 0 | 返回 list1 中的第1个元素 |
根据偏移量 index 范围获取 List 中的元素 | lrange | lrange list1 0 2 | 返回 list1 中的第1、2、3 个元素 |
根据偏移量 index 范围获取 Sorted Set 中的元素 | zrange | zrange sset1 0 2 | 返回 sset1 中的第1、2、3 个元素 |
删除操作 | 命令 | 示例 | 备注 |
---|---|---|---|
删除字符串 | del | del name | 键值对 {"name": "zhang"} |
删除整个 HashMap | del | del map1 | 键值对 {"map1": {"id": 1, "name": "zhang", "age": 88}} |
删除整个 Set | del | del s1 | 无 |
删除整个 SortedSet | del | del ss1 | 无 |
删除整个 List | del | del list1 | 无 |
剔除 HashMap 中的某个键值对 | hdel | hdel map1 id | 其中 id 是该键 |
根据 value 剔除 List 中指定的元素 | lrem | lrem list1 -2 a | 即在list1中从后向前找,剔除2个值为a的元素;其中 -2 是count,负号表示方向从后向前,2 表示要剔除的个数,list1 中满足条件的元素数量可小于count绝对值,如果count是0,则剔除所有满足条件的元素 |
剔除 List 中的最左侧元素 | lpop | lpop list1 | 比如 list1原来是 redis、oracle,执行该操作后为 oracle |
剔除 List 中的最右侧元素 | rpop | rpop list1 | 比如 list1原来是 redis、oracle,执行该操作后为 redis |
剔除(随机) set 中 count 个元素 | spop | spop set1 2 | 其中2为count |
其他操作 | 命令 | 示例 | 备注 |
---|---|---|---|
查看 Redis 安装路径 | CONFIG GET dir | CONFIG GET dir | 无 |
清屏 | clear | clear | 清空屏幕,但不会清除数据 |
获取某个命令的用途 | help | help HKEYS | HKEYS key, summary: Get all the fields in a hash since: 2.0.0, group: hash |
密码登录 | auth | auth root | 其中root是配置文件redis.conf中requirepass配置项的值,即密码 |
退出当前客户端链接 | quit | quit | 无 |
测试客户端能否连接到redis-server | ping | ping | 如果返回pong,说明连接成功 |
查看整个 Redis 的状态信息 | info | info | 无 |
查看某个数据库的状态信息 | info keyspace | keyspace | 无 |
切换数据库 | select | select 1 | 切换为序号为1的数据库(启动 redis-client 时默认是序号为0的数据库) |
删除 Redis 中的所有key | flushdb | flushdb | 无 |
后台持久化数据 | bgsave | bgsave | 无 |
返回当前数据库的 Key 个数 | dbsize | ||
删除当前数据中的所有 Key | flushdb | flushdb | 无 |
删除 Redis 中的所有 Key | flushall | flushall | 无 |
获取 HashMap 中的元素个数 | hlen | hlen map1 | 无 |
获取 List 中的元素个数 | llen | llen list1 | 无 |
获取 Set 中的元素个数 | scard | scard set1 | 无 |
获取 Sorted Set 中的元素个数 | zcar | zcard set1 | 无 |
列出 Redis 中的所有 key | keys | keys * | 无 |
获取 HashMap 中所有key | hkeys | hkeys map1 | 无 |
获取 HashMap 中所有value | hvals | hvals map1 | 无 |
获取 HashMap 中所有键值对 | hgetall | hgetall map1 | 无 |
获取 List 中的所有元素 | lrange | lrange list 0 list1的元素个数 | 无 |
获取 Set 中的所有元素 | smembers | smembers set1 | 无 |
四、API 调用方法
4.1 Java 操作 Redis
impor redis.clients.jedis.Jedis;
import java.util.Map;
import java.util.Set;
public class RedisUtil {
Jedis jd = null;
String pass = null;
String host = null;
int port = 6370;
public RedisUtil(String host, int port, String pass) {
this.host = host;
this.port = port;
this.pass = pass;
init();
}
private void init() {
#
jd = new Jedis(host, port, 1000);
jd.auth(pass);
}
public void setKV(String key, String val) {
jd.set(key, val);
System.out.println(String.format(">>>>>> Jedis set K-V: (%s, %s).", key, jd.get(key)));
}
public void getKV(String key) {
jd.hgetAll(key);
System.out.println(String.format(">>>>>> Jedis get K-V: (%s, %s).", key, jd.hgetAll(key)));
}
public void setHM(String hmKey, Map<String, String> map) {
jd.hset(hmKey, map);
}
public void rmHMField(String hmKey, String field) {
if (jd.exists(hmKey)) {
if (jd.hget(hmKey, field) != null) {
jd.hdel(hmKey, field);
System.out.println(String.format(">>>>>> The field %s in Hashmap %s is deleted.", field, hmKey));
} else {
System.out.println(String.format(">>>>>> This field %s does not exist in the HashMap.", field));
}
} else {
System.out.println(String.format(">>>>>> The key %s does not exist.", hmKey));
}
}
public Set<String> getAllKeys(String pattern) {
return jd.keys(pattern);
}
public String getRedisInfo() {
System.out.println(">>>>>> Redis info: ");
return jd.info();
}
public boolean exeEval(String script, int keyCnt, String ... args) {
boolean succeed = true;
try {
jd.eval(script, keyCnt, args);
} catch (Exception e) {
e.printStackTrace();
succeed = false;
}
return succeed;
}
public boolean exeEvalSha(String script, int keyCnt, String ... args) {
boolean succeed = true;
String sha1 = jd.scriptLoad(script);
System.out.println(">>>>>> Script sha1: " + sha1);
try {
jd.evalsha(sha1, keyCnt, args);
} catch (Exception e) {
e.printStackTrace();
}
return succeed;
}
}
// 主方法
import java.util.HashMap;
import java.util.Map;
public class Main {
public static void main(String[] args) {
String pass = "root";
String host = "localhost";
int port = 6379;
String script = "redis.call('set',KEYS[1],ARGV[1]);redis.call('set',KEYS[2],ARGV[2]);return 'OK';";
int keyCnt = 2;
String hmKey = "map1";
Map<String, String> map = new HashMap<>();
map.put("id", "1");
map.put("name", "zhang");
map.put("age", "88");
RedisUtil redisUtil = new RedisUtil(host, port, pass);
redisUtil.setKV("name", "zhang");
redisUtil.setHM(hmKey, map);
redisUtil.rmHMField(hmKey, "addr");
redisUtil.rmHMField(hmKey, "id");
redisUtil.exeEvalSha(script, keyCnt, "k2", "k3", "v2", "v3");
redisUtil.exeEval(script, keyCnt, "k2", "k3", "v2", "v3");
redisUtil.getKV(hmKey);
System.out.println(redisUtil.getRedisInfo());
}
}
'```
执行结果:
```bash
>>>>>> Jedis set K-V: (name, zhang).
>>>>>> This field addr does not exist in the HashMap.
>>>>>> The field id in Hashmap map1 is deleted.
>>>>>> Script sha1: 046ab9327f94abbe991894063370234cb4add8f7
>>>>>> Jedis get K-V: (map1, {name=zhang, age=88}).
>>>>>> Redis info:
# Server
redis_version:5.0.6
redis_git_sha1:00000000
redis_git_dirty:0
redis_build_id:25f7d67ca5603fd3
redis_mode:standalone
os:Darwin 17.7.0 x86_64
......
4.2 Python 操作 Redis
# RedisUtil.py
# _*_coding:UTF-8 _*_
import redis
import traceback
class RedisUtil(object):
password = None
host = None
port = None
redis_instance = None
def __init__(self, password, host, port):
self.password = password
self.host = host
self.port = port
self.init()
pass
def init(self):
# 默认host为localhost即127.0.0.1, 默认port为6379,默认无密码,默认链接的是数据库DB0
pool = redis.ConnectionPool(host=self.host, port=self.port, password=self.password)
self.redis_instance = redis.Redis(connection_pool=pool)
def setKV(self, key, val):
instance = self.redis_instance
instance.set(key, val)
print(">>>>>> Jedis set K-V: (%s, %s)." % (key, instance.get(key)))
def getKV(self, key):
instance = self.redis_instance
print(">>>>>> Jedis get K-V: (%s, %s)." % (key, str(instance.hgetall(key))))
def setHM(self, hmKey, map):
self.redis_instance.hmset(hmKey, map)
def rmHMField(self, hmKey, field):
instance = self.redis_instance
if instance.exists(hmKey):
if instance.hget(hmKey, field):
instance.hdel(hmKey, field)
print(">>>>>> The field %s in Hashmap %s is deleted." % (field, hmKey))
else:
print(">>>>>> This field %s does not exist in the HashMap." % field)
else:
print(">>>>>> The key %s does not exist." % hmKey)
def getAllKeys(self, pattern):
return self.redis_instance.keys(pattern)
def getRedisInfo(self):
print(">>>>>> Redis info: ")
return self.redis_instance.info()
def exeEval(self, script, keyCnt, *args):
succeed = True
try:
self.redis_instance.eval(script, keyCnt, *args)
except Exception as e:
print(e.args)
print('=======')
print(traceback.format_exc())
succeed = False
return succeed
def exeEvalSha(self, script, keyCnt, *args):
succeed = True
instance = self.redis_instance
sha1 = instance.script_load(script)
print(">>>>>> Script sha1: " + sha1)
try:
instance.evalsha(sha1, keyCnt, *args)
except Exception as e:
print(e.args)
print('=======')
print(traceback.format_exc())
succeed = False
return succeed
# Main.py
# _*_ coding: UTF-8 _*_
from com.saicmotor.comunity.redis.RedisUtil import RedisUtil
class Main(object):
password = "root"
host = "localhost"
port = 6379
script = "redis.call('set',KEYS[1],ARGV[1]);redis.call('set',KEYS[2],ARGV[2]);return 'OK';"
keyCnt = 2
hmKey = "map1"
map = {"id": "1", "name": "zhang", "age": "88"}
print(type(map))
def __init__(self):
pass
redisUtil = RedisUtil(password, host, port)
redisUtil.setKV("name", "zhang")
redisUtil.setHM(hmKey, map)
redisUtil.rmHMField(hmKey, "addr")
redisUtil.rmHMField(hmKey, "id")
redisUtil.exeEvalSha(script, keyCnt, "k2", "k3", "v2", "v3")
redisUtil.exeEval(script, keyCnt, "k2", "k3", "v2", "v3")
redisUtil.getKV(hmKey)
print(redisUtil.getRedisInfo())
五、测试结果
>>>>>> Jedis set K-V: (name, b'zhang').
>>>>>> This field addr does not exist in the HashMap.
>>>>>> The field id in Hashmap map1 is deleted.
>>>>>> Script sha1: 046ab9327f94abbe991894063370234cb4add8f7
>>>>>> Jedis get K-V: (map1, {b'name': b'zhang', b'age': b'88'}).
>>>>>> Redis info:
{'redis_version': '5.0.6', 'redis_git_sha1': 0, 'redis_git_dirty': 0, 'redis_build_id': '25f7d67ca5603fd3', 'redis_mode': 'standalone', 'os': 'Darwin 17.7.0 x86_64', 'arch_bits': 64, 'multiplexing_api': 'kqueue', 'atomicvar_api': 'atomic-builtin', 'gcc_version': '4.2.1', 'process_id': 6995, 'run_id': '35277b80e7feb26f961e1dabc9e86509ba855a5f', 'tcp_port': 6379, 'uptime_in_seconds': 103869, 'uptime_in_days': 1, 'hz': 10, 'configured_hz': 10, 'lru_clock': 14126255, 'executable': '/Users/ycaha/redis-server', 'config_file': '/Users/ycaha/software-package-install/redis_install/redis-5.0.6/redis.conf', 'connected_clients': 2, 'client_recent_max_input_buffer': 2, 'client_recent_max_output_buffer': 0, 'blocked_clients': 0, 'used_memory': 1059488, 'used_memory_human': '1.01M', 'used_memory_rss': 1183744, 'used_memory_rss_human': '1.13M', 'used_memory_peak': 1059488, 'used_memory_peak_human': '1.01M', 'used_memory_peak_perc': '100.00%', 'used_memory_overhead': 1054880, 'used_memory_startup': 987616, 'used_memory_dataset': 4608, 'used_memory_dataset_perc': '6.41%', 'allocator_allocated': 1006784, 'allocator_active': 1143808, 'allocator_resident': 1143808, 'total_system_memory': 8589934592, 'total_system_memory_human': '8.00G', 'used_memory_lua': 40960, 'used_memory_lua_human': '40.00K', 'used_memory_scripts': 200, 'used_memory_scripts_human': '200B', 'number_of_cached_scripts': 1, 'maxmemory': 0, 'maxmemory_human': '0B', 'maxmemory_policy': 'noeviction', 'allocator_frag_ratio': 1.14, 'allocator_frag_bytes': 137024, 'allocator_rss_ratio': 1.0, 'allocator_rss_bytes': 0, 'rss_overhead_ratio': 1.03, 'rss_overhead_bytes': 39936, 'mem_fragmentation_ratio': 1.18, 'mem_fragmentation_bytes': 176960, 'mem_not_counted_for_evict': 0, 'mem_replication_backlog': 0, 'mem_clients_slaves': 0, 'mem_clients_normal': 66616, 'mem_aof_buffer': 0, 'mem_allocator': 'libc', 'active_defrag_running': 0, 'lazyfree_pending_objects': 0, 'loading': 0, 'rdb_changes_since_last_save': 21, 'rdb_bgsave_in_progress': 0, 'rdb_last_save_time': 1574407139, 'rdb_last_bgsave_status': 'ok', 'rdb_last_bgsave_time_sec': 0, 'rdb_current_bgsave_time_sec': -1, 'rdb_last_cow_size': 0, '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, 'total_connections_received': 59, 'total_commands_processed': 717, 'instantaneous_ops_per_sec': 0, 'total_net_input_bytes': 29464, 'total_net_output_bytes': 91506, 'instantaneous_input_kbps': 0.0, 'instantaneous_output_kbps': 0.0, 'rejected_connections': 0, 'sync_full': 0, 'sync_partial_ok': 0, 'sync_partial_err': 0, 'expired_keys': 0, 'expired_stale_perc': 0.0, 'expired_time_cap_reached_count': 0, 'evicted_keys': 0, 'keyspace_hits': 237, 'keyspace_misses': 1, 'pubsub_channels': 0, 'pubsub_patterns': 0, 'latest_fork_usec': 373, '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, 'role': 'master', 'connected_slaves': 0, 'master_replid': '26134abea51a96eca5e4f70066268898829f00d6', 'master_replid2': 0, '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, 'used_cpu_sys': 149.487102, 'used_cpu_user': 68.878745, 'used_cpu_sys_children': 0.056271, 'used_cpu_user_children': 0.014674, 'cluster_enabled': 0, 'db0': {'keys': 7, 'expires': 0, 'avg_ttl': 0}, 'db1': {'keys': 1, 'expires': 0, 'avg_ttl': 0}}
Process finished with exit code 0
笔者水平有限,如有错误,敬请指正!
网友评论