• docker系列6:docker安装redis


    传送门

    docker系列1:docker安装

    docker系列2:阿里云镜像加速器

     docker系列3:docker镜像基本命令

    docker系列4:docker容器基本命令

    docker系列5:docker安装nginx

    Docker安装redis

    通过前面4节,对docker有了一个基本了解,包括环境安装及镜像与容器的相关操作命令。

    在上一节通过docker安装nginx来体验了一下docker安装的便捷之处,现在通过docker来试试安装redis吧!

    之前通过手工的方式安装过单机版本的redis,步骤还是比较烦琐,那么通过docker安装呢?还是参考nginx安装的流程,首先确定redis的版本!

    确定版本

    之前在linux服务器上面安装了的linux版本较高,后来ECS服务器到期释放了。最后都是直接用的windows上面的,版本较低:

    这次就直接上最新的,通过docker在docker hub上面查找: 

    拉取镜像

    确定了redis版本,就可以进行镜像的下载了。

    执行拉取redis镜像

    如上讨论,选择redis最新版本来安装,执行命令docker pull redis:

     docker pull redis

    然后下载成功会显示类似如下信息: 

    查看nginx镜像

    然后再执行镜像查看命令docker images: 

    运行redis

    现在到了第3步了,那就是通过docker来运行redis!

    执行启动redis命令

    这里注意的是,因为选择是最新版本了,所以运行的时候:

    docker run -it -d --name test_redis redis /bin/bash

    查看运行结果

    执行之后,可以docker ps来查看一下:

    验证redis

    经过了上面的三步曲,现在来验证一下redis是否安装成功!可以通过访问服务来验证:

    因为是阿里云服务器, redis默认的端口是6379,直接用客户端工具连接会发现失败了!

    这个原因在就在于容器的端口没有跟服务器端口进行映射!

    端口映射

    把上面的命令稍作修改,并重新启动成功!

    docker run -it -d --name test_redis redis -p 6379:6379 /bin/bash

    端口开放

    注意服务器的端口需要开放,如果是云服务器还在安全组设置一下

    配置文件redis.conf

    在使用Docker容器时,有时候需要对Redis进行配置,但是Docker镜像中并没有默认的redis.conf,如何设置该文件参考docker没有redis.conf,及redis的下载地址,最终命令:

    docker run --name test_redis -p 6379:6379 -v /root/redis/redis.conf:/usr/local/etc/redis/redis.conf -d redis

    再次验证连接信息,显示成功!

    JAVA集成redis

    当redis搭建好之后,可以通过java连接!还是用原来的tsm工程来测试,因为是springboot框架,所以使用spring-boot-starter-data-redis组件。

    pom坐标

    1. <dependency>
    2. <groupId>org.springframework.bootgroupId>
    3. <artifactId>spring-boot-starter-data-redisartifactId>
    4. <version>3.1.3version>
    5. dependency>
    6. <dependency>
    7. <groupId>org.apache.commonsgroupId>
    8. <artifactId>commons-pool2artifactId>
    9. dependency>

    配置文件

    这里使用上面docker搭建的redis,在application.properties文件里面配置如下:

    1. # ====================================================================================
    2. # spring-redis
    3. # ====================================================================================
    4. # 若没有密码,则需要注释这个配置项
    5. # spring.redis.password=
    6. spring.redis.timeout=10000
    7. # 单机,替换成实际的连接地址
    8. spring.redis.host=127.0.0.1
    9. spring.redis.port=6379
    10. spring.redis.lettuce.pool.max-active=8
    11. spring.redis.lettuce.pool.max-wait=-1
    12. spring.redis.lettuce.pool.min-idle=0
    13. spring.redis.lettuce.pool.max-idle=8

    配置类

     这个组件主要是使用RedisTemplate,主要配置文件如下:

    1. import org.springframework.context.annotation.Bean;
    2. import org.springframework.context.annotation.Configuration;
    3. import org.springframework.data.redis.connection.RedisConnectionFactory;
    4. import org.springframework.data.redis.core.RedisTemplate;
    5. import org.springframework.data.redis.core.StringRedisTemplate;
    6. import org.springframework.data.redis.serializer.JdkSerializationRedisSerializer;
    7. import org.springframework.data.redis.serializer.StringRedisSerializer;
    8. @Configuration
    9. public class RedisConfiguration
    10. {
    11. /**
    12. * spring-boot-autoconfigure的RedisAutoConfiguration自动注册的RedisTemplate,使用的序列化器为默人的JdkSerializationRedisSerializer,序列化后生成的是不利于阅读的编码字符串。
    13. * 所以我们手动注册一个RedisTemplate,设置RedisConnectionFactory属性为spring-boot-autoconfigure的JedisConnectionConfiguration/LettuceConnectionConfiguration自动注册的RedisConnectionFactory,并设置序列化器为StringRedisSerializer。
    14. * 其实也可以直接在主启动类中使用@Autowired注入SpringBoot自动注册的RedisTemplate,并添加一个@PostConstruct的方法来修改它的序列化器为StringRedisSerializer。
    15. */
    16. @Bean
    17. public RedisTemplate redisTemplate(RedisConnectionFactory redisConnectionFactory)
    18. {
    19. final RedisTemplate template = new RedisTemplate<>();
    20. // 设置ConnectionFactory,SpringBoot会自动注册ConnectionFactory-Bean
    21. template.setConnectionFactory(redisConnectionFactory);
    22. // 设置序列化器为StringRedisSerializer(默认是 JdkSerializationRedisSerializer , java操作时会产生乱码)
    23. StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
    24. template.setKeySerializer(stringRedisSerializer);
    25. template.setHashKeySerializer(stringRedisSerializer);
    26. template.setHashValueSerializer(stringRedisSerializer);
    27. template.setValueSerializer(new JdkSerializationRedisSerializer());
    28. template.afterPropertiesSet();
    29. return template;
    30. }
    31. /**
    32. * 配置StringRedisTemplate
    33. * @param factory
    34. * @return
    35. */
    36. @Bean
    37. public StringRedisTemplate stringRedisTemplate(
    38. RedisConnectionFactory factory) {
    39. StringRedisTemplate redisTemplate = new StringRedisTemplate();
    40. redisTemplate.setConnectionFactory(factory);
    41. redisTemplate.setKeySerializer(new StringRedisSerializer());
    42. redisTemplate.setHashKeySerializer(new StringRedisSerializer());
    43. return redisTemplate;
    44. }
    45. }

    操作工具类

    针对redis支持的数据类型,可以定制成工具类:

    1. import java.util.List;
    2. import java.util.Map;
    3. import java.util.Set;
    4. import java.util.concurrent.TimeUnit;
    5. import org.springframework.beans.factory.annotation.Autowired;
    6. import org.springframework.data.redis.core.RedisTemplate;
    7. import org.springframework.stereotype.Component;
    8. import org.springframework.util.CollectionUtils;
    9. @Component
    10. public class RedisUtil
    11. {
    12. @Autowired
    13. private RedisTemplate redisTemplate;
    14. // =============================common============================
    15. /**
    16. * 指定缓存失效时间
    17. * @param key 键
    18. * @param time 时间(秒)
    19. * @return
    20. */
    21. public boolean expire(String key, long time) {
    22. try {
    23. if (time > 0) {
    24. redisTemplate.expire(key, time, TimeUnit.SECONDS);
    25. }
    26. return true;
    27. } catch (Exception e) {
    28. e.printStackTrace();
    29. return false;
    30. }
    31. }
    32. /**
    33. * 根据key 获取过期时间
    34. * @param key 键 不能为null
    35. * @return 时间(秒) 返回0代表为永久有效
    36. */
    37. public long getExpire(String key) {
    38. return redisTemplate.getExpire(key, TimeUnit.SECONDS);
    39. }
    40. /**
    41. * 判断key是否存在
    42. * @param key 键
    43. * @return true 存在 false不存在
    44. */
    45. public boolean hasKey(String key) {
    46. try {
    47. return redisTemplate.hasKey(key);
    48. } catch (Exception e) {
    49. e.printStackTrace();
    50. return false;
    51. }
    52. }
    53. /**
    54. * 删除缓存
    55. * @param key 可以传一个值 或多个
    56. */
    57. @SuppressWarnings("unchecked")
    58. public void del(String... key) {
    59. if (key != null && key.length > 0) {
    60. if (key.length == 1) {
    61. redisTemplate.delete(key[0]);
    62. } else {
    63. redisTemplate.delete(CollectionUtils.arrayToList(key));
    64. }
    65. }
    66. }
    67. // ============================String=============================
    68. /**
    69. * 普通缓存获取
    70. * @param key 键
    71. * @return
    72. */
    73. public Object get(String key) {
    74. return key == null ? null : redisTemplate.opsForValue().get(key);
    75. }
    76. /**
    77. * 普通缓存放入
    78. * @param key 键
    79. * @param value 值
    80. * @return true成功 false失败
    81. */
    82. public boolean set(String key, Object value) {
    83. try {
    84. redisTemplate.opsForValue().set(key, value);
    85. return true;
    86. } catch (Exception e) {
    87. e.printStackTrace();
    88. return false;
    89. }
    90. }
    91. /**
    92. * 普通缓存放入并设置时间
    93. * @param key 键
    94. * @param value 值
    95. * @param time 时间(秒) time要大于0 如果time小于等于0 将设置无限期
    96. * @return true成功 false 失败
    97. */
    98. public boolean set(String key, Object value, long time) {
    99. try {
    100. if (time > 0) {
    101. redisTemplate.opsForValue().set(key, value, time, TimeUnit.SECONDS);
    102. } else {
    103. set(key, value);
    104. }
    105. return true;
    106. } catch (Exception e) {
    107. e.printStackTrace();
    108. return false;
    109. }
    110. }
    111. /**
    112. * 递增
    113. * @param key 键
    114. * @param delta 要增加几(大于0)
    115. * @return
    116. */
    117. public long incr(String key, long delta) {
    118. if (delta < 0) {
    119. throw new RuntimeException("递增因子必须大于0");
    120. }
    121. return redisTemplate.opsForValue().increment(key, delta);
    122. }
    123. /**
    124. * 递减
    125. * @param key 键
    126. * @param delta 要减少几(小于0)
    127. * @return
    128. */
    129. public long decr(String key, long delta) {
    130. if (delta < 0) {
    131. throw new RuntimeException("递减因子必须大于0");
    132. }
    133. return redisTemplate.opsForValue().increment(key, -delta);
    134. }
    135. // ================================Map=================================
    136. /**
    137. * HashGet
    138. * @param key 键 不能为null
    139. * @param item 项 不能为null
    140. * @return
    141. */
    142. public Object hget(String key, String item) {
    143. return redisTemplate.opsForHash().get(key, item);
    144. }
    145. /**
    146. * 获取hashKey对应的所有键值
    147. * @param key 键
    148. * @return 对应的多个键值
    149. */
    150. public Map hmget(String key) {
    151. return redisTemplate.opsForHash().entries(key);
    152. }
    153. /**
    154. * HashSet
    155. * @param key 键
    156. * @param map 对应多个键值
    157. * @return true 成功 false 失败
    158. */
    159. public boolean hmset(String key, Map map) {
    160. try {
    161. redisTemplate.opsForHash().putAll(key, map);
    162. return true;
    163. } catch (Exception e) {
    164. e.printStackTrace();
    165. return false;
    166. }
    167. }
    168. /**
    169. * HashSet 并设置时间
    170. * @param key 键
    171. * @param map 对应多个键值
    172. * @param time 时间(秒)
    173. * @return true成功 false失败
    174. */
    175. public boolean hmset(String key, Map map, long time) {
    176. try {
    177. redisTemplate.opsForHash().putAll(key, map);
    178. if (time > 0) {
    179. expire(key, time);
    180. }
    181. return true;
    182. } catch (Exception e) {
    183. e.printStackTrace();
    184. return false;
    185. }
    186. }
    187. /**
    188. * 向一张hash表中放入数据,如果不存在将创建
    189. * @param key 键
    190. * @param item 项
    191. * @param value 值
    192. * @return true 成功 false失败
    193. */
    194. public boolean hset(String key, String item, Object value) {
    195. try {
    196. redisTemplate.opsForHash().put(key, item, value);
    197. return true;
    198. } catch (Exception e) {
    199. e.printStackTrace();
    200. return false;
    201. }
    202. }
    203. /**
    204. * 向一张hash表中放入数据,如果不存在将创建
    205. * @param key 键
    206. * @param item 项
    207. * @param value 值
    208. * @param time 时间(秒) 注意:如果已存在的hash表有时间,这里将会替换原有的时间
    209. * @return true 成功 false失败
    210. */
    211. public boolean hset(String key, String item, Object value, long time) {
    212. try {
    213. redisTemplate.opsForHash().put(key, item, value);
    214. if (time > 0) {
    215. expire(key, time);
    216. }
    217. return true;
    218. } catch (Exception e) {
    219. e.printStackTrace();
    220. return false;
    221. }
    222. }
    223. /**
    224. * 删除hash表中的值
    225. * @param key 键 不能为null
    226. * @param item 项 可以使多个 不能为null
    227. */
    228. public void hdel(String key, Object... item) {
    229. redisTemplate.opsForHash().delete(key, item);
    230. }
    231. /**
    232. * 判断hash表中是否有该项的值
    233. * @param key 键 不能为null
    234. * @param item 项 不能为null
    235. * @return true 存在 false不存在
    236. */
    237. public boolean hHasKey(String key, String item) {
    238. return redisTemplate.opsForHash().hasKey(key, item);
    239. }
    240. /**
    241. * hash递增 如果不存在,就会创建一个 并把新增后的值返回
    242. * @param key 键
    243. * @param item 项
    244. * @param by 要增加几(大于0)
    245. * @return
    246. */
    247. public double hincr(String key, String item, double by) {
    248. return redisTemplate.opsForHash().increment(key, item, by);
    249. }
    250. /**
    251. * hash递减
    252. * @param key 键
    253. * @param item 项
    254. * @param by 要减少记(小于0)
    255. * @return
    256. */
    257. public double hdecr(String key, String item, double by) {
    258. return redisTemplate.opsForHash().increment(key, item, -by);
    259. }
    260. // ============================set=============================
    261. /**
    262. * 根据key获取Set中的所有值
    263. * @param key 键
    264. * @return
    265. */
    266. public Set sGet(String key) {
    267. try {
    268. return redisTemplate.opsForSet().members(key);
    269. } catch (Exception e) {
    270. e.printStackTrace();
    271. return null;
    272. }
    273. }
    274. /**
    275. * 根据value从一个set中查询,是否存在
    276. * @param key 键
    277. * @param value 值
    278. * @return true 存在 false不存在
    279. */
    280. public boolean sHasKey(String key, Object value) {
    281. try {
    282. return redisTemplate.opsForSet().isMember(key, value);
    283. } catch (Exception e) {
    284. e.printStackTrace();
    285. return false;
    286. }
    287. }
    288. /**
    289. * 将数据放入set缓存
    290. * @param key 键
    291. * @param values 值 可以是多个
    292. * @return 成功个数
    293. */
    294. public long sSet(String key, Object... values) {
    295. try {
    296. return redisTemplate.opsForSet().add(key, values);
    297. } catch (Exception e) {
    298. e.printStackTrace();
    299. return 0;
    300. }
    301. }
    302. /**
    303. * 将set数据放入缓存
    304. * @param key 键
    305. * @param time 时间(秒)
    306. * @param values 值 可以是多个
    307. * @return 成功个数
    308. */
    309. public long sSetAndTime(String key, long time, Object... values) {
    310. try {
    311. Long count = redisTemplate.opsForSet().add(key, values);
    312. if (time > 0)
    313. expire(key, time);
    314. return count;
    315. } catch (Exception e) {
    316. e.printStackTrace();
    317. return 0;
    318. }
    319. }
    320. /**
    321. * 获取set缓存的长度
    322. * @param key 键
    323. * @return
    324. */
    325. public long sGetSetSize(String key) {
    326. try {
    327. return redisTemplate.opsForSet().size(key);
    328. } catch (Exception e) {
    329. e.printStackTrace();
    330. return 0;
    331. }
    332. }
    333. /**
    334. * 移除值为value的
    335. * @param key 键
    336. * @param values 值 可以是多个
    337. * @return 移除的个数
    338. */
    339. public long setRemove(String key, Object... values) {
    340. try {
    341. Long count = redisTemplate.opsForSet().remove(key, values);
    342. return count;
    343. } catch (Exception e) {
    344. e.printStackTrace();
    345. return 0;
    346. }
    347. }
    348. // ===============================list=================================
    349. /**
    350. * 获取list缓存的内容
    351. * @param key 键
    352. * @param start 开始
    353. * @param end 结束 0 到 -1代表所有值
    354. * @return
    355. */
    356. public List lGet(String key, long start, long end) {
    357. try {
    358. return redisTemplate.opsForList().range(key, start, end);
    359. } catch (Exception e) {
    360. e.printStackTrace();
    361. return null;
    362. }
    363. }
    364. /**
    365. * 获取list缓存的长度
    366. * @param key 键
    367. * @return
    368. */
    369. public long lGetListSize(String key) {
    370. try {
    371. return redisTemplate.opsForList().size(key);
    372. } catch (Exception e) {
    373. e.printStackTrace();
    374. return 0;
    375. }
    376. }
    377. /**
    378. * 通过索引 获取list中的值
    379. * @param key 键
    380. * @param index 索引 index>=0时, 0 表头,1 第二个元素,依次类推;index<0时,-1,表尾,-2倒数第二个元素,依次类推
    381. * @return
    382. */
    383. public Object lGetIndex(String key, long index) {
    384. try {
    385. return redisTemplate.opsForList().index(key, index);
    386. } catch (Exception e) {
    387. e.printStackTrace();
    388. return null;
    389. }
    390. }
    391. /**
    392. * 将list放入缓存
    393. * @param key 键
    394. * @param value 值
    395. * @param time 时间(秒)
    396. * @return
    397. */
    398. public boolean lSet(String key, Object value) {
    399. try {
    400. redisTemplate.opsForList().rightPush(key, value);
    401. return true;
    402. } catch (Exception e) {
    403. e.printStackTrace();
    404. return false;
    405. }
    406. }
    407. /**
    408. * 将list放入缓存
    409. * @param key 键
    410. * @param value 值
    411. * @param time 时间(秒)
    412. * @return
    413. */
    414. public boolean lSet(String key, Object value, long time) {
    415. try {
    416. redisTemplate.opsForList().rightPush(key, value);
    417. if (time > 0)
    418. expire(key, time);
    419. return true;
    420. } catch (Exception e) {
    421. e.printStackTrace();
    422. return false;
    423. }
    424. }
    425. /**
    426. * 将list放入缓存
    427. * @param key 键
    428. * @param value 值
    429. * @param time 时间(秒)
    430. * @return
    431. */
    432. public boolean lSet(String key, List value) {
    433. try {
    434. redisTemplate.opsForList().rightPushAll(key, value);
    435. return true;
    436. } catch (Exception e) {
    437. e.printStackTrace();
    438. return false;
    439. }
    440. }
    441. /**
    442. * 将list放入缓存
    443. *
    444. * @param key 键
    445. * @param value 值
    446. * @param time 时间(秒)
    447. * @return
    448. */
    449. public boolean lSet(String key, List value, long time) {
    450. try {
    451. redisTemplate.opsForList().rightPushAll(key, value);
    452. if (time > 0)
    453. expire(key, time);
    454. return true;
    455. } catch (Exception e) {
    456. e.printStackTrace();
    457. return false;
    458. }
    459. }
    460. /**
    461. * 根据索引修改list中的某条数据
    462. * @param key 键
    463. * @param index 索引
    464. * @param value 值
    465. * @return
    466. */
    467. public boolean lUpdateIndex(String key, long index, Object value) {
    468. try {
    469. redisTemplate.opsForList().set(key, index, value);
    470. return true;
    471. } catch (Exception e) {
    472. e.printStackTrace();
    473. return false;
    474. }
    475. }
    476. /**
    477. * 移除N个值为value
    478. * @param key 键
    479. * @param count 移除多少个
    480. * @param value 值
    481. * @return 移除的个数
    482. */
    483. public long lRemove(String key, long count, Object value) {
    484. try {
    485. Long remove = redisTemplate.opsForList().remove(key, count, value);
    486. return remove;
    487. } catch (Exception e) {
    488. e.printStackTrace();
    489. return 0;
    490. }
    491. }
    492. }
    493. 代码测试

      写一个测试类,如下:

      1. import com.tw.tsm.base.util.RedisUtil;
      2. import lombok.extern.slf4j.Slf4j;
      3. import org.springframework.beans.factory.annotation.Autowired;
      4. import org.springframework.web.bind.annotation.GetMapping;
      5. import org.springframework.web.bind.annotation.RequestMapping;
      6. import org.springframework.web.bind.annotation.RequestParam;
      7. import org.springframework.web.bind.annotation.RestController;
      8. @RestController
      9. @Slf4j
      10. @RequestMapping("/redis")
      11. public class RedisTestController
      12. {
      13. @Autowired
      14. private RedisUtil redisUtil;
      15. @GetMapping("/set")
      16. public void testSet(@RequestParam("key") String key, @RequestParam("val") String val)
      17. {
      18. redisUtil.set(key, val);
      19. }
      20. @GetMapping("/get")
      21. public String testGet(@RequestParam("key") String key)
      22. {
      23. return (String)redisUtil.get(key);
      24. }
      25. }

    494. 相关阅读:
      多层感知机与DNN算法
      2022-中医基础-《阴阳 20问与答》
      vue3相关内容
      centos 7.7之后,无法远程ssh执行 java -jar 指令
      C语言 memset
      操作符详解
      【剑指Offer】47. 礼物的最大价值
      ES6-04-模块化的暴露:export关键字
      机械硬盘HDD
      多媒体展厅总包制作会面临的问题分析
    495. 原文地址:https://blog.csdn.net/weigeshikebi/article/details/133575938