SlideShare una empresa de Scribd logo
1 de 37
Descargar para leer sin conexión
닷넷에서 Redis 사용하기
티쓰리엔터테인먼트
모바일 1팀
공통 기술 개발팀
최흥배 과장
Redis ?????
Key-Value,
Memory DB
Redis v2.2.12 맛보기
http://www.slideshare.net/knight1128/redis-8896084
REDIS 연구노트
http://kerocat.tistory.com/1
REDIS 공부
http://blog.naver.com/forioso/10173379225
Redis 설치
 http://cs-arthur.tistory.com/113
 http://misoin.tistory.com/1
 http://blog.outsider.ne.kr/763
.NET과 Redis
Redis의 .NET 라이브러리로
'ServiceStack.Redis'와
'BookSleeve'가 있다.
둘 다 Redis 공식 라이브러리
이다
추천!!!
BookSleeve
Stack Overflow에서 근무하고 protobuf-net을 만든 Marc Gravell씨가 만들었다
"모든 것이 비동기로
파이프라인으로 동작
한다"
파이프닝
Client: INCR X
Server: 1
Client: INCR X
Server: 2
Client: INCR X
Server: 3
Client: INCR X
Server: 4
Client: INCR X
Client: INCR X
Client: INCR X
Client: INCR X
Server: 1
Server: 2
Server: 3
Server: 4
파이프닝을 사용하면 클라이
언트와 서버간 통신이 1번으
로 끝난다.
단순히 GET, SET 뿐만이 아
닌 다양한 조작을 파이프닝
할 수 있다
설치
var connection = new RedisConnection("127.0.0.1");
await connection.Open();
var x1 = connection.Strings.Increment(db: 0, key: "X");
var x2 = connection.Strings.Increment(db: 0, key: "X");
var x3 = connection.Strings.Increment(db: 0, key: "X");
var x4 = connection.Strings.Increment(db: 0, key: "X");
await Task.WhenAll(x1, x2, x3, x4); // 모든 완료를 기다린다.
// 결과 표시
Console.WriteLine("{0}, {1}, {2}, {3}", x1.Result, x2.Result, x3.Result, x4.Result);
BookSleeve는 모든 조작이
비동기이기 때문에 반환 값
은 Task 형이 된다.
또 C# 5.0 에서 생긴
async/await 메소드를 사용
하면 비동기 조작을 활용하
기 쉬워진다
암묵적 파이프닝
 [예제 - 1]은 명시적으로 파이프라인을 사용하지 않고 있
다.
 BookSleeves는 내부에서 블럭킹 큐를 사용하여 명령어
를 축척하고 있다.
 또 큐가 비었는지 감시하고, 명령어를 보내는(네트워크로)
워커가 동작하고 있다.
 워커가 동작할 때 큐에 복수의 명령어가 축척되면 이것
들이 모두 일괄적으로 파이프닝으로 보낸다.
 즉 같은 타이밍에 발행된 명령어는 자동적으로 파이프닝
화 된다.
 또 네트워크 접근은 비동기 I/O로 소켓 통신을 하므로 파
이프닝 송신 동안의 대기 시간은 최소화 시킨다
연결 관리
RedisConnection 오브젝트(=Redis 서버로의 접속)는 단독으로 열지 않고 공유
하고 있다. 접속을 관리하도록 아래와 같은 코드를 준비한다
public static class RedisConnectionManager
{
static RedisConnection connection;
static object connectionLock = new object();
public static RedisConnection GetConnection()
{
if ((connection == null)
|| ( (connection.State != RedisConnectionBase.ConnectionState.Open) &&
(connection.State != RedisConnectionBase.ConnectionState.Opening) ))
{
lock (connectionLock)
{
if ((connection == null)
|| ( (connection.State != RedisConnectionBase.ConnectionState.Open) &&
(connection.State != RedisConnectionBase.ConnectionState.Opening) ))
{
connection = new RedisConnection("127.0.0.1"); // 접속 설정은 변경한다
connection.Wait(connection.Open());
}
}
}
return connection;
}
}
var redis = RedisConnectionManager.GetConnection();
await redis.Strings.Set(db: 0, key: "jacking", value: "흥배");
var value = await redis.Strings.Get(db: 0, key: "jacking");
RedisConnection은 모든 요청에서 공유된다.
ASP.NET에서는 모든 독립된 리퀘스트, 관련 없는 모
든 다른 명령어가 파이프닝화 되어 모아서 보내므로
큰 폭으로 Round Trip Time 이 줄어든다
BookSleeve
좀 귀찮은 -_-
왜? BookSleeve 에서 제공하는 API는 원시
수준으로 대부분의 반환형이 byte[] 이다.
그래서 대부분 시리얼라이즈를 통해서
오브젝트로 변환해야 한다
CloudStructures
https://github.com/neuecc/CloudStructures
직렬화,
접속 관리,
클라이언트 사이드에서 분산,
.config 파일에서 설정 읽기
BookSleeve
var settings = new RedisSettings("127.0.0.1");
var list = new RedisList<person>(settings, "Person-Key-0");
await list.AddLast(new Person { Name = "AAA", Age = 20 });
await list.AddLast(new Person { Name = "BBB", Age = 35 });
var persons = await list.Range(0, 2);
RedisSettings
var settings = new RedisSettings("127.0.0.1");
// 연결할지 않았다면 연결 후 객체를 반환한다.
var conn = settings.GetConnection();
데이터 직렬화 방법
new RedisSettings("127.0.0.1",
converter: new JsonRedisValueConverter());
new RedisSettings("127.0.0.1",
converter: new ProtoBufRedisValueConverter());
RedisSettings
2개 이상의 redis 서버를 수평 분할로 사용하고 싶을 때 사용한다.
// multi group of connections
var group = new RedisGroup(groupName: "Cache", settings: new[]
{
new RedisSettings(host: "100.0.0.1", port: 6379, db: 0),
new RedisSettings(host: "105.0.0.1", port: 6379, db: 0),
});
// key hashing. key 값으로 어느쪽의 redis 서버를 사용할지 선택할 수 있다.
var conn = group.GetSettings("hogehoge-100").GetConnection();
public static RedisGroup redisGroup = null;
//var addressList = new List<Tuple<string,int>>();
//addressList.Add(new Tuple<string, int>("172.20.60.208",6379));
//addressList.Add(new Tuple<string, int>("172.20.60.208", 6380));
public static void Init(List<Tuple<string, int>> addressList)
{
var redisSettings = new RedisSettings[addressList.Count];
for (int i = 0; i < addressList.Count; ++i)
{
redisSettings[i] = new RedisSettings(host: addressList[i].Item1, port:
addressList[i].Item2, db: 0);
}
redisGroup = new RedisGroup(groupName: "GameServer", settings:
redisSettings);
}
사례: Redis 샤딩
var list = new
CloudStructures.Redis.RedisList<int>(GlobalSettings.Default, "listkey1");
// 모든 값을 지운다.
await list.Clear();
// 제일 뒤에 추가
await list.AddLast(1);
await list.AddLast(10);
// 제일 앞에 추가
await list.AddFirst(100);
await list.AddFirst(1000);
// 총 갯수
await list.GetLength();
// redis 명령어 중 LRANGE 기능
// 리스트의 0번째부터 시작해서 3개
await list.Range(0, 2); // 1000, 100, 1
사례: list
사례: hash
public class UserAuthInfo
{
public string ID;
public string PW;
public string AuthToken;
public Int64 UnqiueNumber;
}
static async Task<UserAuthInfo> GetAccountInfo(string id)
{
var redisObj = new RedisClass<UserAuthInfo>(MemoryDB.redisGroup, id);
var userData = new UserAuthInfo();
userData = await redisObj.GetValue();
return userData;
}
static void SaveAccountInfo(UserAuthInfo userAuth)
{
var redisObj = new RedisClass<UserAuthInfo>(MemoryDB.redisGroup, userAuth.ID);
redisObj.SetValue(userAuth);
}
Configuration
<configSections>
<section name="cloudStructures"
type="CloudStructures.Redis.CloudStructuresConfigurationSection, CloudStructures" />
</configSections>
<cloudStructures>
<redis>
<group name="cache">
<add host="127.0.0.1" />
<add host="127.0.0.2" port="1000" />
</group>
<group name="session">
<add host="127.0.0.1" db="2"
valueConverter="CloudStructures.Redis.ProtoBufRedisValueConverter, CloudStructures" />
</group>
</redis>
</cloudStructures>
var groups = CloudStructuresConfigurationSection.GetSection().ToRedisGroups()
Redis와 Lua
lua 사용
public async Task<double> IncrementLimitByMin(double value, double min, bool
queueJump = false)
{
using (Monitor.Start(Settings.PerformanceMonitor, Key, CallType))
{
var v = Connection.Scripting.Eval(Settings.Db, @"
local inc = tonumber(ARGV[1])
local min = tonumber(ARGV[2])
local x = tonumber(redis.call('incrbyfloat', KEYS[1], inc))
if(x < min) then
redis.call('set', KEYS[1], min)
x = min
end
return tostring(x)", new[] { Key }, new object[] { value, min }, useCache: true,
inferStrings: true, queueJump: queueJump);
return double.Parse((string)(await v.ConfigureAwait(false)));
}
}
 https://code.google.com/p/booksleeve/
 http://www.buildinsider.net/small/rediscshap/01
 https://github.com/neuecc/CloudStructures
참고
닷넷프레임워크에서 Redis 사용하기

Más contenido relacionado

La actualidad más candente

Kubernetes intro public - kubernetes meetup 4-21-2015
Kubernetes intro   public - kubernetes meetup 4-21-2015Kubernetes intro   public - kubernetes meetup 4-21-2015
Kubernetes intro public - kubernetes meetup 4-21-2015Rohit Jnagal
 
画像生成AI stable diffusionの紹介
画像生成AI stable diffusionの紹介画像生成AI stable diffusionの紹介
画像生成AI stable diffusionの紹介iPride Co., Ltd.
 
【de:code 2020】 React Native で Windows アプリ開発 ~React Native for Windows~
【de:code 2020】 React Native で Windows アプリ開発 ~React Native for Windows~【de:code 2020】 React Native で Windows アプリ開発 ~React Native for Windows~
【de:code 2020】 React Native で Windows アプリ開発 ~React Native for Windows~日本マイクロソフト株式会社
 
초심자를 위한 도커 소개 및 입문
초심자를 위한 도커 소개 및 입문초심자를 위한 도커 소개 및 입문
초심자를 위한 도커 소개 및 입문Daniel Seo
 
SPAのルーティングの話
SPAのルーティングの話SPAのルーティングの話
SPAのルーティングの話ushiboy
 
インタフェース完全に理解した
インタフェース完全に理解したインタフェース完全に理解した
インタフェース完全に理解したtorisoup
 
A quick tour of the Cysharp OSS
A quick tour of the Cysharp OSSA quick tour of the Cysharp OSS
A quick tour of the Cysharp OSSYoshifumi Kawai
 
関数型・オブジェクト指向 宗教戦争に疲れたなたに送るGo言語入門
関数型・オブジェクト指向宗教戦争に疲れたなたに送るGo言語入門関数型・オブジェクト指向宗教戦争に疲れたなたに送るGo言語入門
関数型・オブジェクト指向 宗教戦争に疲れたなたに送るGo言語入門Tadahiro Ishisaka
 
Docker란 무엇인가? : Docker 기본 사용법
Docker란 무엇인가? : Docker 기본 사용법Docker란 무엇인가? : Docker 기본 사용법
Docker란 무엇인가? : Docker 기본 사용법pyrasis
 
Intégration continue et déploiement continue avec Jenkins
Intégration continue et déploiement continue avec JenkinsIntégration continue et déploiement continue avec Jenkins
Intégration continue et déploiement continue avec JenkinsKokou Gaglo
 
Dockerを使ったローカルでの開発から本番環境へのデプロイまで
Dockerを使ったローカルでの開発から本番環境へのデプロイまでDockerを使ったローカルでの開発から本番環境へのデプロイまで
Dockerを使ったローカルでの開発から本番環境へのデプロイまでRyo Nakamaru
 
Flutter移行の苦労と、乗り越えた先に得られたもの
Flutter移行の苦労と、乗り越えた先に得られたものFlutter移行の苦労と、乗り越えた先に得られたもの
Flutter移行の苦労と、乗り越えた先に得られたものRecruit Lifestyle Co., Ltd.
 
190119 unreal engine c++ 입문 및 팁
190119 unreal engine c++ 입문 및 팁190119 unreal engine c++ 입문 및 팁
190119 unreal engine c++ 입문 및 팁KWANGIL KIM
 
アプリケーション性能管理(APM)ツールの新世代 「AppDynamics」のご紹介 – OpenStack最新情報セミナー 2015年7月
アプリケーション性能管理(APM)ツールの新世代 「AppDynamics」のご紹介 – OpenStack最新情報セミナー 2015年7月アプリケーション性能管理(APM)ツールの新世代 「AppDynamics」のご紹介 – OpenStack最新情報セミナー 2015年7月
アプリケーション性能管理(APM)ツールの新世代 「AppDynamics」のご紹介 – OpenStack最新情報セミナー 2015年7月VirtualTech Japan Inc.
 
Openstack zun,virtual kubelet
Openstack zun,virtual kubeletOpenstack zun,virtual kubelet
Openstack zun,virtual kubeletChanyeol yoon
 
Spring bootでweb セキュリティ(ログイン認証)編
Spring bootでweb セキュリティ(ログイン認証)編Spring bootでweb セキュリティ(ログイン認証)編
Spring bootでweb セキュリティ(ログイン認証)編なべ
 
OSSを利用したプロジェクト管理
OSSを利用したプロジェクト管理OSSを利用したプロジェクト管理
OSSを利用したプロジェクト管理Tadashi Miyazato
 

La actualidad más candente (20)

Kubernetes intro public - kubernetes meetup 4-21-2015
Kubernetes intro   public - kubernetes meetup 4-21-2015Kubernetes intro   public - kubernetes meetup 4-21-2015
Kubernetes intro public - kubernetes meetup 4-21-2015
 
画像生成AI stable diffusionの紹介
画像生成AI stable diffusionの紹介画像生成AI stable diffusionの紹介
画像生成AI stable diffusionの紹介
 
【de:code 2020】 React Native で Windows アプリ開発 ~React Native for Windows~
【de:code 2020】 React Native で Windows アプリ開発 ~React Native for Windows~【de:code 2020】 React Native で Windows アプリ開発 ~React Native for Windows~
【de:code 2020】 React Native で Windows アプリ開発 ~React Native for Windows~
 
Maven
MavenMaven
Maven
 
초심자를 위한 도커 소개 및 입문
초심자를 위한 도커 소개 및 입문초심자를 위한 도커 소개 및 입문
초심자를 위한 도커 소개 및 입문
 
SPAのルーティングの話
SPAのルーティングの話SPAのルーティングの話
SPAのルーティングの話
 
インタフェース完全に理解した
インタフェース完全に理解したインタフェース完全に理解した
インタフェース完全に理解した
 
A quick tour of the Cysharp OSS
A quick tour of the Cysharp OSSA quick tour of the Cysharp OSS
A quick tour of the Cysharp OSS
 
Hibernate
HibernateHibernate
Hibernate
 
関数型・オブジェクト指向 宗教戦争に疲れたなたに送るGo言語入門
関数型・オブジェクト指向宗教戦争に疲れたなたに送るGo言語入門関数型・オブジェクト指向宗教戦争に疲れたなたに送るGo言語入門
関数型・オブジェクト指向 宗教戦争に疲れたなたに送るGo言語入門
 
Docker란 무엇인가? : Docker 기본 사용법
Docker란 무엇인가? : Docker 기본 사용법Docker란 무엇인가? : Docker 기본 사용법
Docker란 무엇인가? : Docker 기본 사용법
 
Intégration continue et déploiement continue avec Jenkins
Intégration continue et déploiement continue avec JenkinsIntégration continue et déploiement continue avec Jenkins
Intégration continue et déploiement continue avec Jenkins
 
Dockerを使ったローカルでの開発から本番環境へのデプロイまで
Dockerを使ったローカルでの開発から本番環境へのデプロイまでDockerを使ったローカルでの開発から本番環境へのデプロイまで
Dockerを使ったローカルでの開発から本番環境へのデプロイまで
 
Flutter移行の苦労と、乗り越えた先に得られたもの
Flutter移行の苦労と、乗り越えた先に得られたものFlutter移行の苦労と、乗り越えた先に得られたもの
Flutter移行の苦労と、乗り越えた先に得られたもの
 
190119 unreal engine c++ 입문 및 팁
190119 unreal engine c++ 입문 및 팁190119 unreal engine c++ 입문 및 팁
190119 unreal engine c++ 입문 및 팁
 
アプリケーション性能管理(APM)ツールの新世代 「AppDynamics」のご紹介 – OpenStack最新情報セミナー 2015年7月
アプリケーション性能管理(APM)ツールの新世代 「AppDynamics」のご紹介 – OpenStack最新情報セミナー 2015年7月アプリケーション性能管理(APM)ツールの新世代 「AppDynamics」のご紹介 – OpenStack最新情報セミナー 2015年7月
アプリケーション性能管理(APM)ツールの新世代 「AppDynamics」のご紹介 – OpenStack最新情報セミナー 2015年7月
 
Openstack zun,virtual kubelet
Openstack zun,virtual kubeletOpenstack zun,virtual kubelet
Openstack zun,virtual kubelet
 
Spring bootでweb セキュリティ(ログイン認証)編
Spring bootでweb セキュリティ(ログイン認証)編Spring bootでweb セキュリティ(ログイン認証)編
Spring bootでweb セキュリティ(ログイン認証)編
 
OSSを利用したプロジェクト管理
OSSを利用したプロジェクト管理OSSを利用したプロジェクト管理
OSSを利用したプロジェクト管理
 
Nouveautés de java 8
Nouveautés de java 8Nouveautés de java 8
Nouveautés de java 8
 

Similar a 닷넷프레임워크에서 Redis 사용하기

Node Js와 Redis를 사용한 구조화된 데이터
Node Js와 Redis를 사용한 구조화된 데이터Node Js와 Redis를 사용한 구조화된 데이터
Node Js와 Redis를 사용한 구조화된 데이터jinho park
 
Do IoT Yourself! - 사물 간의 연결을 위한 Open API
Do IoT Yourself! - 사물 간의 연결을 위한 Open APIDo IoT Yourself! - 사물 간의 연결을 위한 Open API
Do IoT Yourself! - 사물 간의 연결을 위한 Open APIHyunghun Cho
 
7가지 동시성 모델 람다아키텍처
7가지 동시성 모델  람다아키텍처7가지 동시성 모델  람다아키텍처
7가지 동시성 모델 람다아키텍처Sunggon Song
 
Create-React-App으로 SSR을 구현하며 배운 점 (feat. TypeScript)
Create-React-App으로 SSR을 구현하며 배운 점 (feat. TypeScript)Create-React-App으로 SSR을 구현하며 배운 점 (feat. TypeScript)
Create-React-App으로 SSR을 구현하며 배운 점 (feat. TypeScript)LanarkSeung
 
파이썬 데이터베이스 연결 1탄
파이썬 데이터베이스 연결 1탄파이썬 데이터베이스 연결 1탄
파이썬 데이터베이스 연결 1탄SeongHyun Ahn
 
파이썬 데이터베이스 연결 2탄
파이썬 데이터베이스 연결 2탄파이썬 데이터베이스 연결 2탄
파이썬 데이터베이스 연결 2탄SeongHyun Ahn
 
파이썬 웹프로그래밍 1탄
파이썬 웹프로그래밍 1탄 파이썬 웹프로그래밍 1탄
파이썬 웹프로그래밍 1탄 SeongHyun Ahn
 
MongoDB 하루만에 끝내기
MongoDB 하루만에 끝내기MongoDB 하루만에 끝내기
MongoDB 하루만에 끝내기Seongkuk Park
 
Node.js and react
Node.js and reactNode.js and react
Node.js and reactHyungKuIm
 
JSP 빠르게 시작하기
JSP 빠르게 시작하기JSP 빠르게 시작하기
JSP 빠르게 시작하기Park JoongSoo
 
Naver api for android
Naver api for androidNaver api for android
Naver api for androidSangon Lee
 
Do IoT Yourself 3rd : Open API - revision 3
Do IoT Yourself 3rd : Open API - revision 3Do IoT Yourself 3rd : Open API - revision 3
Do IoT Yourself 3rd : Open API - revision 3Hyunghun Cho
 
[Td 2015]windows, linux, mac 신경 안 쓴다. .net 2015와 더더 좋아지는 c# 살짝 훔쳐보기(김명신)
[Td 2015]windows, linux, mac 신경 안 쓴다. .net 2015와 더더 좋아지는 c# 살짝 훔쳐보기(김명신)[Td 2015]windows, linux, mac 신경 안 쓴다. .net 2015와 더더 좋아지는 c# 살짝 훔쳐보기(김명신)
[Td 2015]windows, linux, mac 신경 안 쓴다. .net 2015와 더더 좋아지는 c# 살짝 훔쳐보기(김명신)Sang Don Kim
 
02.실행환경 실습교재(데이터처리)
02.실행환경 실습교재(데이터처리)02.실행환경 실습교재(데이터처리)
02.실행환경 실습교재(데이터처리)Hankyo
 
Tech Update - The Future of .NET Framework (김명신 부장)
Tech Update - The Future of .NET Framework (김명신 부장)Tech Update - The Future of .NET Framework (김명신 부장)
Tech Update - The Future of .NET Framework (김명신 부장)Eunbee Song
 
IoT Web App - 수집된 정보의 가공, 처리, 융합
IoT Web App - 수집된 정보의 가공, 처리, 융합IoT Web App - 수집된 정보의 가공, 처리, 융합
IoT Web App - 수집된 정보의 가공, 처리, 융합Hyunghun Cho
 
세션1. block chain as a platform
세션1. block chain as a platform세션1. block chain as a platform
세션1. block chain as a platformJay JH Park
 

Similar a 닷넷프레임워크에서 Redis 사용하기 (20)

Node Js와 Redis를 사용한 구조화된 데이터
Node Js와 Redis를 사용한 구조화된 데이터Node Js와 Redis를 사용한 구조화된 데이터
Node Js와 Redis를 사용한 구조화된 데이터
 
Do IoT Yourself! - 사물 간의 연결을 위한 Open API
Do IoT Yourself! - 사물 간의 연결을 위한 Open APIDo IoT Yourself! - 사물 간의 연결을 위한 Open API
Do IoT Yourself! - 사물 간의 연결을 위한 Open API
 
7가지 동시성 모델 람다아키텍처
7가지 동시성 모델  람다아키텍처7가지 동시성 모델  람다아키텍처
7가지 동시성 모델 람다아키텍처
 
Redis
RedisRedis
Redis
 
Create-React-App으로 SSR을 구현하며 배운 점 (feat. TypeScript)
Create-React-App으로 SSR을 구현하며 배운 점 (feat. TypeScript)Create-React-App으로 SSR을 구현하며 배운 점 (feat. TypeScript)
Create-React-App으로 SSR을 구현하며 배운 점 (feat. TypeScript)
 
파이썬 데이터베이스 연결 1탄
파이썬 데이터베이스 연결 1탄파이썬 데이터베이스 연결 1탄
파이썬 데이터베이스 연결 1탄
 
파이썬 데이터베이스 연결 2탄
파이썬 데이터베이스 연결 2탄파이썬 데이터베이스 연결 2탄
파이썬 데이터베이스 연결 2탄
 
파이썬 웹프로그래밍 1탄
파이썬 웹프로그래밍 1탄 파이썬 웹프로그래밍 1탄
파이썬 웹프로그래밍 1탄
 
MongoDB 하루만에 끝내기
MongoDB 하루만에 끝내기MongoDB 하루만에 끝내기
MongoDB 하루만에 끝내기
 
Node.js and react
Node.js and reactNode.js and react
Node.js and react
 
[Codelab 2017] ReactJS 기초
[Codelab 2017] ReactJS 기초[Codelab 2017] ReactJS 기초
[Codelab 2017] ReactJS 기초
 
JSP 빠르게 시작하기
JSP 빠르게 시작하기JSP 빠르게 시작하기
JSP 빠르게 시작하기
 
Naver api for android
Naver api for androidNaver api for android
Naver api for android
 
Mongo db 최범균
Mongo db 최범균Mongo db 최범균
Mongo db 최범균
 
Do IoT Yourself 3rd : Open API - revision 3
Do IoT Yourself 3rd : Open API - revision 3Do IoT Yourself 3rd : Open API - revision 3
Do IoT Yourself 3rd : Open API - revision 3
 
[Td 2015]windows, linux, mac 신경 안 쓴다. .net 2015와 더더 좋아지는 c# 살짝 훔쳐보기(김명신)
[Td 2015]windows, linux, mac 신경 안 쓴다. .net 2015와 더더 좋아지는 c# 살짝 훔쳐보기(김명신)[Td 2015]windows, linux, mac 신경 안 쓴다. .net 2015와 더더 좋아지는 c# 살짝 훔쳐보기(김명신)
[Td 2015]windows, linux, mac 신경 안 쓴다. .net 2015와 더더 좋아지는 c# 살짝 훔쳐보기(김명신)
 
02.실행환경 실습교재(데이터처리)
02.실행환경 실습교재(데이터처리)02.실행환경 실습교재(데이터처리)
02.실행환경 실습교재(데이터처리)
 
Tech Update - The Future of .NET Framework (김명신 부장)
Tech Update - The Future of .NET Framework (김명신 부장)Tech Update - The Future of .NET Framework (김명신 부장)
Tech Update - The Future of .NET Framework (김명신 부장)
 
IoT Web App - 수집된 정보의 가공, 처리, 융합
IoT Web App - 수집된 정보의 가공, 처리, 융합IoT Web App - 수집된 정보의 가공, 처리, 융합
IoT Web App - 수집된 정보의 가공, 처리, 융합
 
세션1. block chain as a platform
세션1. block chain as a platform세션1. block chain as a platform
세션1. block chain as a platform
 

Más de 흥배 최

Twitter의 snowflake 소개 및 활용
Twitter의 snowflake 소개 및 활용Twitter의 snowflake 소개 및 활용
Twitter의 snowflake 소개 및 활용흥배 최
 
Go web framework 비교[번역 정리]
Go web framework 비교[번역 정리]Go web framework 비교[번역 정리]
Go web framework 비교[번역 정리]흥배 최
 
Bash on Ubuntu on Windows
Bash on Ubuntu on WindowsBash on Ubuntu on Windows
Bash on Ubuntu on Windows흥배 최
 
잘 알려지지 않은 숨은 진주, Winsock API - WSAPoll, Fast Loopback
잘 알려지지 않은 숨은 진주, Winsock API - WSAPoll, Fast Loopback잘 알려지지 않은 숨은 진주, Winsock API - WSAPoll, Fast Loopback
잘 알려지지 않은 숨은 진주, Winsock API - WSAPoll, Fast Loopback흥배 최
 
KGC 2016 오픈소스 네트워크 엔진 Super socket 사용하기
KGC 2016 오픈소스 네트워크 엔진 Super socket 사용하기KGC 2016 오픈소스 네트워크 엔진 Super socket 사용하기
KGC 2016 오픈소스 네트워크 엔진 Super socket 사용하기흥배 최
 
Wtl 개요와 설치
Wtl 개요와 설치Wtl 개요와 설치
Wtl 개요와 설치흥배 최
 
KGC2015_C# 스크립트를 사용한 게임서버 모니터링 시스템개발
KGC2015_C# 스크립트를 사용한 게임서버 모니터링 시스템개발KGC2015_C# 스크립트를 사용한 게임서버 모니터링 시스템개발
KGC2015_C# 스크립트를 사용한 게임서버 모니터링 시스템개발흥배 최
 
Modern C++ 프로그래머를 위한 CPP11/14 핵심
Modern C++ 프로그래머를 위한 CPP11/14 핵심Modern C++ 프로그래머를 위한 CPP11/14 핵심
Modern C++ 프로그래머를 위한 CPP11/14 핵심흥배 최
 
닷넷 Apache avro
닷넷 Apache avro닷넷 Apache avro
닷넷 Apache avro흥배 최
 
Mongodb2.2와 2.4의 신 기능 소개
Mongodb2.2와 2.4의 신 기능 소개Mongodb2.2와 2.4의 신 기능 소개
Mongodb2.2와 2.4의 신 기능 소개흥배 최
 
Mongodb 관리
Mongodb 관리Mongodb 관리
Mongodb 관리흥배 최
 
Mongodb 개발 포인트
Mongodb 개발 포인트Mongodb 개발 포인트
Mongodb 개발 포인트흥배 최
 
NET 최선단 기술에 의한 고성능 웹 애플리케이션
NET 최선단 기술에 의한 고성능 웹 애플리케이션NET 최선단 기술에 의한 고성능 웹 애플리케이션
NET 최선단 기술에 의한 고성능 웹 애플리케이션흥배 최
 
ASP.NET과 C#으로 개발하는 대규모 소셜 게임
ASP.NET과 C#으로 개발하는 대규모 소셜 게임ASP.NET과 C#으로 개발하는 대규모 소셜 게임
ASP.NET과 C#으로 개발하는 대규모 소셜 게임흥배 최
 
Twitter의 대규모 시스템 운용 기술 어느 고래의 배속에서
Twitter의 대규모 시스템 운용 기술 어느 고래의 배속에서Twitter의 대규모 시스템 운용 기술 어느 고래의 배속에서
Twitter의 대규모 시스템 운용 기술 어느 고래의 배속에서흥배 최
 
Twitter에 있어서 대규모 시스템 구성, 3개의 원칙과 시스템
Twitter에 있어서 대규모 시스템 구성, 3개의 원칙과 시스템Twitter에 있어서 대규모 시스템 구성, 3개의 원칙과 시스템
Twitter에 있어서 대규모 시스템 구성, 3개의 원칙과 시스템흥배 최
 
MongoDB 모바일 게임 개발에 사용
MongoDB 모바일 게임 개발에 사용MongoDB 모바일 게임 개발에 사용
MongoDB 모바일 게임 개발에 사용흥배 최
 
Tdc2013 선배들에게 배우는 server scalability
Tdc2013 선배들에게 배우는 server scalabilityTdc2013 선배들에게 배우는 server scalability
Tdc2013 선배들에게 배우는 server scalability흥배 최
 
[KGC 2012]Boost.asio를 이용한 네트웍 프로그래밍
[KGC 2012]Boost.asio를 이용한 네트웍 프로그래밍[KGC 2012]Boost.asio를 이용한 네트웍 프로그래밍
[KGC 2012]Boost.asio를 이용한 네트웍 프로그래밍흥배 최
 

Más de 흥배 최 (20)

Twitter의 snowflake 소개 및 활용
Twitter의 snowflake 소개 및 활용Twitter의 snowflake 소개 및 활용
Twitter의 snowflake 소개 및 활용
 
Go web framework 비교[번역 정리]
Go web framework 비교[번역 정리]Go web framework 비교[번역 정리]
Go web framework 비교[번역 정리]
 
Bash on Ubuntu on Windows
Bash on Ubuntu on WindowsBash on Ubuntu on Windows
Bash on Ubuntu on Windows
 
잘 알려지지 않은 숨은 진주, Winsock API - WSAPoll, Fast Loopback
잘 알려지지 않은 숨은 진주, Winsock API - WSAPoll, Fast Loopback잘 알려지지 않은 숨은 진주, Winsock API - WSAPoll, Fast Loopback
잘 알려지지 않은 숨은 진주, Winsock API - WSAPoll, Fast Loopback
 
KGC 2016 오픈소스 네트워크 엔진 Super socket 사용하기
KGC 2016 오픈소스 네트워크 엔진 Super socket 사용하기KGC 2016 오픈소스 네트워크 엔진 Super socket 사용하기
KGC 2016 오픈소스 네트워크 엔진 Super socket 사용하기
 
Wtl 개요와 설치
Wtl 개요와 설치Wtl 개요와 설치
Wtl 개요와 설치
 
KGC2015_C# 스크립트를 사용한 게임서버 모니터링 시스템개발
KGC2015_C# 스크립트를 사용한 게임서버 모니터링 시스템개발KGC2015_C# 스크립트를 사용한 게임서버 모니터링 시스템개발
KGC2015_C# 스크립트를 사용한 게임서버 모니터링 시스템개발
 
Modern C++ 프로그래머를 위한 CPP11/14 핵심
Modern C++ 프로그래머를 위한 CPP11/14 핵심Modern C++ 프로그래머를 위한 CPP11/14 핵심
Modern C++ 프로그래머를 위한 CPP11/14 핵심
 
NLog 소개
NLog 소개NLog 소개
NLog 소개
 
닷넷 Apache avro
닷넷 Apache avro닷넷 Apache avro
닷넷 Apache avro
 
Mongodb2.2와 2.4의 신 기능 소개
Mongodb2.2와 2.4의 신 기능 소개Mongodb2.2와 2.4의 신 기능 소개
Mongodb2.2와 2.4의 신 기능 소개
 
Mongodb 관리
Mongodb 관리Mongodb 관리
Mongodb 관리
 
Mongodb 개발 포인트
Mongodb 개발 포인트Mongodb 개발 포인트
Mongodb 개발 포인트
 
NET 최선단 기술에 의한 고성능 웹 애플리케이션
NET 최선단 기술에 의한 고성능 웹 애플리케이션NET 최선단 기술에 의한 고성능 웹 애플리케이션
NET 최선단 기술에 의한 고성능 웹 애플리케이션
 
ASP.NET과 C#으로 개발하는 대규모 소셜 게임
ASP.NET과 C#으로 개발하는 대규모 소셜 게임ASP.NET과 C#으로 개발하는 대규모 소셜 게임
ASP.NET과 C#으로 개발하는 대규모 소셜 게임
 
Twitter의 대규모 시스템 운용 기술 어느 고래의 배속에서
Twitter의 대규모 시스템 운용 기술 어느 고래의 배속에서Twitter의 대규모 시스템 운용 기술 어느 고래의 배속에서
Twitter의 대규모 시스템 운용 기술 어느 고래의 배속에서
 
Twitter에 있어서 대규모 시스템 구성, 3개의 원칙과 시스템
Twitter에 있어서 대규모 시스템 구성, 3개의 원칙과 시스템Twitter에 있어서 대규모 시스템 구성, 3개의 원칙과 시스템
Twitter에 있어서 대규모 시스템 구성, 3개의 원칙과 시스템
 
MongoDB 모바일 게임 개발에 사용
MongoDB 모바일 게임 개발에 사용MongoDB 모바일 게임 개발에 사용
MongoDB 모바일 게임 개발에 사용
 
Tdc2013 선배들에게 배우는 server scalability
Tdc2013 선배들에게 배우는 server scalabilityTdc2013 선배들에게 배우는 server scalability
Tdc2013 선배들에게 배우는 server scalability
 
[KGC 2012]Boost.asio를 이용한 네트웍 프로그래밍
[KGC 2012]Boost.asio를 이용한 네트웍 프로그래밍[KGC 2012]Boost.asio를 이용한 네트웍 프로그래밍
[KGC 2012]Boost.asio를 이용한 네트웍 프로그래밍
 

닷넷프레임워크에서 Redis 사용하기

  • 1. 닷넷에서 Redis 사용하기 티쓰리엔터테인먼트 모바일 1팀 공통 기술 개발팀 최흥배 과장
  • 7. Redis 설치  http://cs-arthur.tistory.com/113  http://misoin.tistory.com/1  http://blog.outsider.ne.kr/763
  • 9. Redis의 .NET 라이브러리로 'ServiceStack.Redis'와 'BookSleeve'가 있다. 둘 다 Redis 공식 라이브러리 이다
  • 10. 추천!!! BookSleeve Stack Overflow에서 근무하고 protobuf-net을 만든 Marc Gravell씨가 만들었다
  • 11.
  • 13. 파이프닝 Client: INCR X Server: 1 Client: INCR X Server: 2 Client: INCR X Server: 3 Client: INCR X Server: 4 Client: INCR X Client: INCR X Client: INCR X Client: INCR X Server: 1 Server: 2 Server: 3 Server: 4
  • 14. 파이프닝을 사용하면 클라이 언트와 서버간 통신이 1번으 로 끝난다. 단순히 GET, SET 뿐만이 아 닌 다양한 조작을 파이프닝 할 수 있다
  • 16. var connection = new RedisConnection("127.0.0.1"); await connection.Open(); var x1 = connection.Strings.Increment(db: 0, key: "X"); var x2 = connection.Strings.Increment(db: 0, key: "X"); var x3 = connection.Strings.Increment(db: 0, key: "X"); var x4 = connection.Strings.Increment(db: 0, key: "X"); await Task.WhenAll(x1, x2, x3, x4); // 모든 완료를 기다린다. // 결과 표시 Console.WriteLine("{0}, {1}, {2}, {3}", x1.Result, x2.Result, x3.Result, x4.Result);
  • 17. BookSleeve는 모든 조작이 비동기이기 때문에 반환 값 은 Task 형이 된다. 또 C# 5.0 에서 생긴 async/await 메소드를 사용 하면 비동기 조작을 활용하 기 쉬워진다
  • 18. 암묵적 파이프닝  [예제 - 1]은 명시적으로 파이프라인을 사용하지 않고 있 다.  BookSleeves는 내부에서 블럭킹 큐를 사용하여 명령어 를 축척하고 있다.  또 큐가 비었는지 감시하고, 명령어를 보내는(네트워크로) 워커가 동작하고 있다.  워커가 동작할 때 큐에 복수의 명령어가 축척되면 이것 들이 모두 일괄적으로 파이프닝으로 보낸다.  즉 같은 타이밍에 발행된 명령어는 자동적으로 파이프닝 화 된다.  또 네트워크 접근은 비동기 I/O로 소켓 통신을 하므로 파 이프닝 송신 동안의 대기 시간은 최소화 시킨다
  • 19. 연결 관리 RedisConnection 오브젝트(=Redis 서버로의 접속)는 단독으로 열지 않고 공유 하고 있다. 접속을 관리하도록 아래와 같은 코드를 준비한다 public static class RedisConnectionManager { static RedisConnection connection; static object connectionLock = new object(); public static RedisConnection GetConnection() { if ((connection == null) || ( (connection.State != RedisConnectionBase.ConnectionState.Open) && (connection.State != RedisConnectionBase.ConnectionState.Opening) )) { lock (connectionLock) { if ((connection == null) || ( (connection.State != RedisConnectionBase.ConnectionState.Open) && (connection.State != RedisConnectionBase.ConnectionState.Opening) )) { connection = new RedisConnection("127.0.0.1"); // 접속 설정은 변경한다 connection.Wait(connection.Open()); } } } return connection; } }
  • 20. var redis = RedisConnectionManager.GetConnection(); await redis.Strings.Set(db: 0, key: "jacking", value: "흥배"); var value = await redis.Strings.Get(db: 0, key: "jacking"); RedisConnection은 모든 요청에서 공유된다. ASP.NET에서는 모든 독립된 리퀘스트, 관련 없는 모 든 다른 명령어가 파이프닝화 되어 모아서 보내므로 큰 폭으로 Round Trip Time 이 줄어든다
  • 22. 왜? BookSleeve 에서 제공하는 API는 원시 수준으로 대부분의 반환형이 byte[] 이다. 그래서 대부분 시리얼라이즈를 통해서 오브젝트로 변환해야 한다
  • 24.
  • 25. 직렬화, 접속 관리, 클라이언트 사이드에서 분산, .config 파일에서 설정 읽기 BookSleeve
  • 26. var settings = new RedisSettings("127.0.0.1"); var list = new RedisList<person>(settings, "Person-Key-0"); await list.AddLast(new Person { Name = "AAA", Age = 20 }); await list.AddLast(new Person { Name = "BBB", Age = 35 }); var persons = await list.Range(0, 2);
  • 27. RedisSettings var settings = new RedisSettings("127.0.0.1"); // 연결할지 않았다면 연결 후 객체를 반환한다. var conn = settings.GetConnection(); 데이터 직렬화 방법 new RedisSettings("127.0.0.1", converter: new JsonRedisValueConverter()); new RedisSettings("127.0.0.1", converter: new ProtoBufRedisValueConverter());
  • 28. RedisSettings 2개 이상의 redis 서버를 수평 분할로 사용하고 싶을 때 사용한다. // multi group of connections var group = new RedisGroup(groupName: "Cache", settings: new[] { new RedisSettings(host: "100.0.0.1", port: 6379, db: 0), new RedisSettings(host: "105.0.0.1", port: 6379, db: 0), }); // key hashing. key 값으로 어느쪽의 redis 서버를 사용할지 선택할 수 있다. var conn = group.GetSettings("hogehoge-100").GetConnection();
  • 29. public static RedisGroup redisGroup = null; //var addressList = new List<Tuple<string,int>>(); //addressList.Add(new Tuple<string, int>("172.20.60.208",6379)); //addressList.Add(new Tuple<string, int>("172.20.60.208", 6380)); public static void Init(List<Tuple<string, int>> addressList) { var redisSettings = new RedisSettings[addressList.Count]; for (int i = 0; i < addressList.Count; ++i) { redisSettings[i] = new RedisSettings(host: addressList[i].Item1, port: addressList[i].Item2, db: 0); } redisGroup = new RedisGroup(groupName: "GameServer", settings: redisSettings); } 사례: Redis 샤딩
  • 30. var list = new CloudStructures.Redis.RedisList<int>(GlobalSettings.Default, "listkey1"); // 모든 값을 지운다. await list.Clear(); // 제일 뒤에 추가 await list.AddLast(1); await list.AddLast(10); // 제일 앞에 추가 await list.AddFirst(100); await list.AddFirst(1000); // 총 갯수 await list.GetLength(); // redis 명령어 중 LRANGE 기능 // 리스트의 0번째부터 시작해서 3개 await list.Range(0, 2); // 1000, 100, 1 사례: list
  • 31. 사례: hash public class UserAuthInfo { public string ID; public string PW; public string AuthToken; public Int64 UnqiueNumber; } static async Task<UserAuthInfo> GetAccountInfo(string id) { var redisObj = new RedisClass<UserAuthInfo>(MemoryDB.redisGroup, id); var userData = new UserAuthInfo(); userData = await redisObj.GetValue(); return userData; } static void SaveAccountInfo(UserAuthInfo userAuth) { var redisObj = new RedisClass<UserAuthInfo>(MemoryDB.redisGroup, userAuth.ID); redisObj.SetValue(userAuth); }
  • 32. Configuration <configSections> <section name="cloudStructures" type="CloudStructures.Redis.CloudStructuresConfigurationSection, CloudStructures" /> </configSections> <cloudStructures> <redis> <group name="cache"> <add host="127.0.0.1" /> <add host="127.0.0.2" port="1000" /> </group> <group name="session"> <add host="127.0.0.1" db="2" valueConverter="CloudStructures.Redis.ProtoBufRedisValueConverter, CloudStructures" /> </group> </redis> </cloudStructures> var groups = CloudStructuresConfigurationSection.GetSection().ToRedisGroups()
  • 34.
  • 35. lua 사용 public async Task<double> IncrementLimitByMin(double value, double min, bool queueJump = false) { using (Monitor.Start(Settings.PerformanceMonitor, Key, CallType)) { var v = Connection.Scripting.Eval(Settings.Db, @" local inc = tonumber(ARGV[1]) local min = tonumber(ARGV[2]) local x = tonumber(redis.call('incrbyfloat', KEYS[1], inc)) if(x < min) then redis.call('set', KEYS[1], min) x = min end return tostring(x)", new[] { Key }, new object[] { value, min }, useCache: true, inferStrings: true, queueJump: queueJump); return double.Parse((string)(await v.ConfigureAwait(false))); } }