A-B test?

  • 이름 그대로 a안과 b안을 고객에게 테스트 해보는 것

    • 비교를 통해 어떤 방식이 더 좋은지 정략적으로 비교 가능하다
  • e.g 사이트의 ui를 a집단과 b집단을 뽑아 제공

    • 어떤 집단이 저 좋은 결과를 도출해내는지 확인
    • Pasted image 20231004185126.png
    • 위와 같이 UI를 바꾸는 AB-Test를 하니 기부를 5%더 많이 했다고 한다.

주의점

  • 중요한 것은 집단을 추출할 땐 임의적 할당을 해야 한다.
    • 주관이 들어가면 주관에 의한 차이인지, 테스트에 의한 차이인지 모호해짐

단점

  1. 테스트 기간 동안 매출 손실이 발생할 수 있다.
  2. 테스트 기준 이외의 문제가 발생할 수 있다
    1. e.g 쇼핑몰 UI를 변경했는데, 현실의 옷의 트렌드가 변경됨
  3. 특정 기준에서만 A-B Test를 하니 전역이 아닌 지역 최적점만 도출 할 수도 있다.

[ Reference ]


개인적으로 공부한 내용 포스팅 중
잘못된 정보는 지적해주시면 좋겠습니다!

'프로그래밍 및 IT > Analysis' 카테고리의 다른 글

Cohort 분석  (0) 2023.10.04
Funnel 분석  (0) 2023.10.04
게임 지표 용어  (0) 2023.10.04
  • Cohort :특정 기간 동안 공통된 특성 혹은 경험을 갖는 사용자 집단
    • 간단히 말하면 같은 조건의 집단의 기간 별 변화를 보는 것
  • 조건은 세분화 하면 좋다
    • Simpson’paradox
      • A와 B를 전체 비교시 A가 더 좋지만 세분화 해서 보면 B가 더 좋을 수 있다

대표적인 인사이트

  1. 사용자 유지 및 이탈 패턴
    1. 게임 기준으로 사용자의 TS 와 같은 기준을 이용하여 기간에 따라 확인하면 줄어드는 부분을 확인하여 개선 포인트를 잡을 수 있다.
  2. 코호트 간 상이한 행동 패턴
    1. 매출로 예를 들면 신규 유저와 기존 유저의 매출 현황을 볼 수 있다.
1월 2월 3월 4월 5월 6월
NRU 10 10 10 10 10 10
RU 10 20 30 40 50 60
1개월 100 90 80 70 60 50
2개월 150 140 130 120 110
3개월 200 190 180 170
4개월 250 240 230
5개월 300 290
6개월 350
SUM 100 240 420 640 900 1200
  • 위 표를 예시로 들면
    1. NRU(신규 등록 유저) 가 매달 10명씩 늘어난다
    2. NRU의 매출은 매달 50씩 늘어난다
      1. 빨간색으로 칠해진 수치가 신규유저 매출
    3. RU(기존 유저)의 매출은 매달 10씩 줄어든다
    • RU의 매출은 완만히 줄어들고, NRU의 매출은 증가추세다
      • 고로 좋은 방향으로 가고있다
    • 비교는 대각선으로 하는 것이 좋다
      • e.g NRU는 NRU끼리 비교, 1달차는 1달차끼리…
      • 옆으로 row를 밀면 아래와 같다
      • 가로로는 감소지만, 아래로는 증가다.
        • 시간이 지나면서 점점 매출이 증가 중.
1달차 2달차 3달차 4달차 5달차 6달차
1월 100 90 80 70 60 50
2월 150 140 130 120 110
3월 200 190 180 170
4월 250 240 230
5월 300 290
6월 350

[ Reference ]


개인적으로 공부한 내용 포스팅 중
잘못된 정보는 지적해주시면 좋겠습니다!

'프로그래밍 및 IT > Analysis' 카테고리의 다른 글

AB_Test  (0) 2023.10.04
Funnel 분석  (0) 2023.10.04
게임 지표 용어  (0) 2023.10.04
  • Funnel 즉 깔대기 분석이다.
  • 특정 조건들을 추가하면서 최종 목표까지의 전환율을 보는 분석
    • 즉 이탈율이 큰 지점을 알아내는 것이 목적
  • 위 과정을 통해 서비스의 취약점 및 개선점을 찾을 수 있다.
    Pasted image 20230925173230.png
  • 위 사진과 같이 필터링이 됨에 따라 고객의 수가 줄어간다.
    • 위 과정을 보면 어떤 단계에서 이탈을 하는지 확인 가능하다.

SQL로 구현

  • 간단하게 구현하면 다음과 같다.
    • 간단하게 하기 위해 select절의 schema는 user_iddistinct_user_id로만 작성
-- 해당 기간동안 접속한 유저들
with visit as (
	select
	    distinct_user_id
	from user_tb
	group by 1
	where eventdate between "start-date" and "end-date"
) ,
-- 유저중 회원가입 한 유저
with signup as (
   select
		distinct_user_id
	from visit a
	inner join user_tb b on b.user_id = user_id = a.distinct_user_id
	where is_signup = true
),
-- 활동을 하는 유저
with au as (
   select
		distinct_user_id
	from signup a
	inner join user_tb b on b.user_id = user_id = a.distinct_user_id
	where is_active = true
),
-- 구매 한 유저
with pu as (
   select
		distinct_user_id
	from au a
	inner join user_tb b on b.user_id = user_id = a.distinct_user_id
	where is_paying = true
) ,
with funnel_tb as (
select 'visit' as step ,count(1) as user_cnt from visit
union
select 'sigh up' as step ,count(1) as user_cnt from signup
union
select 'au' as step ,count(1) as user_cnt from au
union
select 'pu' as step ,count(1) as user_cnt from pu
)

select step
	 , user_cnt
	 , user_cnt / lag(user_cnt, 1) over () as drop_off
from funnel_tb;
  • 간단하게 보면 위와 같이 볼 수 있다.

AARRR

  • Dave McClure가 만든 분석 프레임워크
  1. Acquisition(획득)
    • 회사 입장에서 고객이 생기는 것.
      • 다운로드, 사이트 방문, 등이 존재한다
      • CAC : 고객 획득 비용
        • 1명의 고객을 획득하는데 사용한 비용.
        • 광고비 : 300 , 유입 고객 : 100 -> CAC : 3
      • DAU/MAU (Daily Active User / Monthly Active User)
        • 전체 유저가 아닌 일간, 월간 방문 유저
  2. Activation(활성화)
    • 고객 중 실제로 활동을 하는 고객
      • PV (Page View)
        • 명칭 그대로 Page를 본 횟수
      • DT(Duration Time) , TS(Time spent) , MTS (Mutigame Time Spent) …
        • DT , TS : 서비스, 게임을 소비한 시간
        • MTS : 실질적으로 게임을 플레이 한 시간
      • Aha Moment
        • 제품의 핵심 가치를 고객이 경험하는 순간
          • 회사마다 본인들이 정한 기준점
  3. Retention(유지)
    • 고객의 재방문
      • Retention Rate
        • 고객 유지 비율
        • 고객 20명 , Retention Rate : 50%
          • 1달 지나면 10명 남고, 그 다음 달은 5명이 남을 것을 예상
      • Churn Rate
        • 이탈 비율
        • 고객 20명 , Churn Rate : 50%
          • 1달 지나면 10명 이탈, 그 다음 달은 5명이 이탈할 것을 예상
  4. Revenue(수익)
    • 실질적으로 물건등을 구매한 것
      • LTV ( Life Time Value)
        • 1명의 고객이 구매(이익)의 총합
          • 1명의 고객이 1,2,3,4,5 만원을 달마다 사용
          • 1+2+3+4+5 = 15만원 사용
          • 해당 고객의 LTV = 15만원
      • PU (Paying User)
        • 구매한 유저
      • ARPU (Average Revenue Per User)
        • 수익 / 모든 고객
      • ARPPU (Average Revenu Per Paying User)
        • 수익 / PU
  5. Referral(추천)
    • SNS홍보 이벤트, 추천인 가입
      • Referral Traffic
        • 여러 체널에서 유입된 트래픽에 따라 어디서 유입됬는지 확인 가능

[ Reference ]


개인적으로 공부한 내용 포스팅 중
잘못된 정보는 지적해주시면 좋겠습니다!

'프로그래밍 및 IT > Analysis' 카테고리의 다른 글

AB_Test  (0) 2023.10.04
Cohort 분석  (0) 2023.10.04
게임 지표 용어  (0) 2023.10.04

ARM Model

  1. Acquisition 고객 확보
  2. Retention 고객 유지
  3. Monetization 유료화

지표 용어

유저 관련 지표

용어 설명
UV ( Unique Visitor ) 특정 기간 동안 방문 유저의 합, 중복 불
DAU ( Daily Active User ) 일 단위 UV
WAU ( Weekly Active User) 주 단위 UV
MAU ( Monthly Active User) 월 단위 UV
RU ( Resistered User) 가입자 수
ARU ( Return Resistered User) 누적 가입자 수
RRU ( Return Resistered User) 복귀 유저 수
NRU ( New Resistered User) 신규 유저 수
MCU ( Maximum Concurrent User ) 최고 동시접속 자 수
Retention 특정 기간 별 재접속 유저 수
Churn 이탈 유저
Stickness 고착도, 2개의 기준 접속률 e.g DAU/MAU * 100
Organic User 자연 유입 , 광고 없이 유입한 유저
Non-Organic User 광고 유입 , 광고 등을 통해 유저
  1. 유저 접속 관련 지표
  2. 특정 기간 단위로 나눠 분석
  3. 목표
    1. NRU 높이기
      1. 신규 유입은 아주 중요하다
      2. 게임 오픈 시 모객 마케팅에서 신경써야할 지표
    2. Retention 관리
      1. 신규 유입이 많더라도, 재방문이 낮으면 게임은 죽어가는 것 이다.
      2. 게임 퀄리티를 보여주는 지표로 사용 가능
          1. 1000명이 유입 되었지만, 남아있는 유저는 200명, 20%만 남아있다
    3. 휴먼유저 관리
    4. DAU,MAU 높이기

매출 관련 지표

용어 설명
PU ( Paying User) 1회 이상 결제한 유저
Non-PU (Non Paying User) 결제를 하지 않은 유저
PPU (Pay Per User ) PU / 접속 유저 (기간별 누적)
ARPPU (Average Revenue Per Paying User ) 전체 결재액 / PU (기간별 누적)
ARPU ( Average Revenue Per User ) 전체 결재액 / 전체 유저 (기간별 누적)
LTV ( Life Time Value) 유저 당 결제금액
  1. PPU가 너무 낮으면, 유료 아이템 설계가 잘못 되어있을 가능성이 높다
    1. 위 공식은 100% 올바르다고 볼 수 없다. 예측치 이기 때문에 상황에 따라 유동적으로 진행해야한다.

마케팅 관련 지표

용어 설명
광고 단가
UAC ( User Acquisition Cost ) 유저 획득 비용
CPI ( Cost Per Install ) 설치 시 비용
CPA/CPE ( Cost Per Action/Engagement) 앱 실행 혹은 앱 내 행위에 의한 과금
CPC ( Cost Per Click) 광고 클릭 시 과금
CPM ( Cost Per Mille) 1000번 노출 시 과금
K-Factor 유저 1명 가입 시 추천 등을 통한 추가 가입 비용
광고 /비용
Impression 광고 노출 수
CTR ( Click Though Rate) Impression 당 클릭률
CR ( Conversion Rate) 전환율, e.g 앱설치..
eCPM ( Effective Cost Per Mille ) 유효 1000 노출 당 광고주에게 지불하는 비용
eCPI ( Effective Cost Per Install) 유효 설치당 비용

[ Reference ]


개인적으로 공부한 내용 포스팅 중
잘못된 정보는 지적해주시면 좋겠습니다!

'프로그래밍 및 IT > Analysis' 카테고리의 다른 글

AB_Test  (0) 2023.10.04
Cohort 분석  (0) 2023.10.04
Funnel 분석  (0) 2023.10.04

Spark?

  • Hadoop과 유사한 클러스터 기반의 분산처리 기능을 제공하는 오픈소스 프레임워크
    • 빅데이터 분산처리 플랫폼 / 엔진
  • In-Memory기반으로 처리하기 때문에 반복적인 데이터 처리, 즉 ML 과 같은 것에 뛰어난 성능을 보인다.

Spark Application

  • 제출한 Job을 Task로 변환하여 Executor에게 분산 처리함

Driver

  • 스파크에서 Job을 수행하는 프로그램
    • Main함수를 수행하는 프로그램
    • SparkContext를 생성하고 해당 Instance를 포함한 프로그램
  • Cluster모드에 따라 다른 위치에서 수행되지만 대체로 실행 서버에서 구동.
  • Worker 노드에 작업을 시키고, 결과를 취합한다

Worker

  • 작업을 하는 노드
  • Executor가 동작하는 노드
    • 작업을 수행하는 프로세스
    • Partition 단위로 Job을 수행
    • 1개의 Worker 노드에 N개의 Executor가 동작할 수 있다

Application

  • Spark 위에서 구동되는 프로그램
    • Driver
      • Spark Application을 실행하는 프로세스
      • Spark Context를 생성
      • Spark Application Life cycle 관리
    • Executor
      • Task 실행을 담당
      • 실행 결과를 Driver에게 전달

Cluster Manager

  • 이름 그대로 cluster를 관리하는 매니져
  • cluster mode 종류
    • Yarn
      • Hadoop Cluster Manager
      • Resource Manager / Node Manager로 구성
    • Memos
      • Apache Cluster Manager
      • Master /Slave 구성
    • StandAlone
      • Spark 자체 제공 Cluster Manager
      • 1 Node 1 Executor만 가능
  • deploy mode
    • client
      • Driver Program을 submit한 곳에서 실행
        • 즉 Client Server에서 Driver을 실행
    • cluster
      • Driver Program을 cluster중 무작위 실행
        • 즉 Client Server이외의 worker Node에서 Driver을 실행

Job

  • Spark Application에 제출된 작업
  • N개의 Task로 구성된 병렬 연산 단위
    • Spark Application은 N+1개의 Job으로 구성됨
  • 각 Job은 DAG로 변환된다
  • Dag에서 각각의 Job Node들은 하나 이상의 Spark Stage에 포함됨

Stage

  • N+1개의 Task의 집합
  • 병렬/순차 적으로 수행될 수 있는 작업을 기반으로 생성됨

Task

  • Executor에서 구동하는 최소 실행 단위

실행 순서

Pasted image 20231004170237.png

  • 간단히 보면 위와 같은 방식으로 Job 1 안에 Stage들을 순차적으로 처리 완료 후 job 2를 수 행한다.
  • 처리 순서
    1. SparkContext를 이용하여 RDD연산 정보를 DAG Scheduler에게 전달
    2. DAG를 생성하면, 해당 DAG를 Cluster Manager에게 전달
    3. 이때 Scheduler는 최대한 locality를 높여 stage를 구성
    4. 생성된 DAG를 수행

데이터 구조

  1. Spark_RDD
  2. DataFrame
  3. DataSet

사용 언어

  1. Java
  2. Scala
  3. R
  4. Python

HA

Spark 또한 Master - Slave 구성으로 되어 있기 때문에 HA구성을 만드는 것이 좋다
만약 HA구성을 하지 않으면 SPOF 위험이 생긴다.
구성 시 Zookeeper 등을 이용하여 사용한다

  • 기본 설정
    • SPARK_DAEMON_JAVA_OPTS에 아래 변수들을 추가한다
      • spark.deploy.recoveryMode=ZOOKEEPER
      • spark.deploy.zookeeper.url=
      • spark.deploy.zookeeper.dir=
        • 기본값 : /spark
    • spark-env.sh에 아래와 같이 추가
      • export SPARK_DAEMON_JAVA_OPTS=“-Dspark.deploy.recoveryMode=ZOOKEEPER -Dspark.deploy.zookeeper.url={zookeeper url} -Dspark.deploy.zookeeper.dir={zookeeper에서 저장할 경로}”
  • HA구성 하지 않고 단일 복구 모드를 사용하고 싶다면 아래와 같이 하면된다
    • spark-env.sh에 아래와 같이 추가
      - export SPARK_DAEMON_JAVA_OPTS=“-Dspark.deploy.recoveryMode=FILESYSTEM -Dspark.deploy.recoveryDirectory={복구 데이터 경로}”

History Server

Spark의 동작을 확인할 수 있는 Web Server

  • Event Log를 확인 할 수 있다
  • HDSF를 사용한다면 아래와 같이 spark-defaults.conf 에 추가하여 후 start-history-server.sh를 실행하여 구동시켜 사용하면 된다.
spark.eventLog.enabled true // 이벤트로그 저장 여부
spark.eventLog.dir hdfs:///spark-history //이벤트 로그 저장
spark.history.fs.logDirectory hdfs:///spark-history // 종료된 App 로그 저장

보유 기능

  1. SparkStreaming
  2. SparkSQL
  3. SparkMLib
  4. SparkGraphx

[ Reference ]


개인적으로 공부한 내용 포스팅 중
잘못된 정보는 지적해주시면 좋겠습니다!

'프로그래밍 및 IT > Spark' 카테고리의 다른 글

spark-scheduling  (0) 2023.11.28
WordCount  (0) 2023.10.13
RDD Action  (0) 2023.10.13
RDD Transformation  (0) 2023.10.13
Spark_RDD  (0) 2023.10.05

Pasted image 20230920011955.png

Kafka?

Pub-Sub 구조의 메시지 큐 Framework

3개의 큰 요소로 구성

  1. Brocker
  2. Producer
  3. Consuker

Kafka는 Disk에 적재된다

  • Disk는 Non-Flash 이기 때문에 영속성을 보장한다.
    • 문제 발생 시 Rewind(재사용) 이 가능하다
  • 사용자가 지정한 기간 동안 데이터를 보관하기 때문에 실시간 / 배치성 모두 지원한다
  • HA / 분산처리를 지원하기 때문에 Scale-Out에 용이하다.
  • Kakfa는 Sequential Scan/write를 기반으로 처리한다
    • 즉, Random Access를 기반으로 처리하지 않기 때문에 SSD보다는 HDD를 권장한다.
    • SSD와 HDD의 1:1비교는 SSD가 성능이 좋을 수 있지만, HDD를 RAID 구성하여 사용한다면 좋은 성능을 야기할 수 있다.
      • 2023-09-20기준 1TB의 SSD의 및 4TB의 HDD의 가격이 동일함
      • 1개만 mount 시키는 것이 아닌 여러개를 mount시킨다면, HDD를 이용하는 것이 더 많은 용양을 확보하고, RAID구성시 성능 또한 보장할 수 있다.
        • Confulent 를 확인하면 상세 정보를 볼 수 있다.
        • 이분의 지금은 운영안 하시는 것 같지만 벤치마크를 잘 정리하신 것이 있어 링크를 걸어둔다.
        • kakao Tech 이것도 보면 설명 잘해주신다.
  • 고성능 데이터 파이프라인, 스트리밍 분석, 데이터 통합 ​​및 미션 크리티컬 애플리케이션을 위해 사용하는 오픈 소스 분산 이벤트 스트리밍 플랫폼
    • 미션 크리티컬 애플리케이션 : 사소한 실수에도 민감한 어플리케이션
  • 고성능 TCP 네트워크 프로토콜을 통해 통신하는 서버 와 클라이언트로 구성된 분산 시스템
  • 높은 처리량, 확장 가능, 영구 저장, 고가용성
  • 사례
    • 메시징, 웹사이트 활동 추적, 측정 항목, 로그 집계, 스트림 처리, 이벤트 소싱, 커밋 로그

요소

Producer

Kafka에 Publish하는 Application으로써 Kafka의 Topic에 메시지를 생성 후 Brokcer에게 전달.

  • 여러 종류의 Producer가 존재한다
    • REST, SparkStream…

Brocker

  • Producer가 Publish한 Topic별 Message를 해당 Topic에 적재
  • Load Balancing / HA를 위해 Cluster를 이루어 동작
    • Failover을 위해 Quorum으로 구성해야한다.
      • Quorum : 홀수로 구성하는 것
  • Kafka Server라고 생각하면 된다.

Consummer

  • Topic에 있는 데이터를 Pull하여 데이터 수집
    • Brocker이 직접 데이터를 제공하는 것이 아닌, 주소 값을 받아 해당 주소에 있는 데이터를 접근하여 가져간다.

Topic

  • Producer가 Brocker에게 전달한 Message를 적재하고 Consumer가 Message를 Pull하는 데이터 저장소
    • 다르긴 하지만, RDB의 Table개념이라고 생각하면된다.
  • Topic은 1+N개의 Partition으로 구성되어 있다.

Partition

  • Topic당 분산되어 적재되는 저장소
    • Partition 개수만큼 분산 처리할 수 있다.
      • Partition 개수만큼 ConsumerConnection을 맺을 수 있다.
    • 분산 처리 하는 만큼 성능 향상을 야기할 수 있다.
      • 너무 많아지면 File Handler 개수 증가, Failover 시간이 증가할 수 있다.
        • File Handler 개수 증가 : 메모리 낭비 야기
        • Failover 시간이 증가 : 말 그대로 장애 복구 시간이 늘어 서버 장애 발생 시 복구 시간이 늘어난다.
          • e.g partition 1개당 1ms가 걸림. 10000개 partition존재 1ms * 10000 : 10초 소요
      • 제한
        • broker당 최대 4000개의 파티션(총계, 여러 topic에 분산)
        • Kafka 클러스터당 최대 200,000개의 파티션(총계, 여러 topic에 분산)
      • 적절한 topic의 partition 개수는?
        • topic에 파티션이 있는 만큼의 소비자를 가질 수 있습니다.
        • 소비자의 배수 : 이를 통해 소비자 그룹의 소비자 간에 파티션을 균등하게 배포
        • 브로커의 배수 : 이 방법을 사용하면 파티션(및 리더!)을 모든 브로커에 균등하게 배포
      • 간단 Partition 수 공식
        • Throughput 기준 : Max(Np, Nc)
          • Np : 시스템 처리량 / partition당 producer 처리량
          • Nc : 시스템 처리량 / partition당 client 처리량
        • Latency 기준
          • 100 * Broker 수 * Replication Factor 수
  • N개의 Replica를 생성하여 데이터 안정성을 유지한다.
    • Replica가 3개 상단의 그림처럼 복제본을 서로 나눠 갖게 된다.
    • Replica를 생성하면 Leader / Follwer로 구성된다.
      • Leader : 데이터 처리를 하는 역할
      • Follwer : Leader를 복제하여 Failover 대비
      • ISR(in-Sync replication)
        • Producer의 옵션 중 Acks가 all일 때 무결성을 위해 복제 여부를 검증하는 Replication
        • Follwer중 ISR로 설정 된 Replica만 Leader가 될 자격을 갖는다
        • replica.lag.time.max.ms 로 설정한 주기마다 데이터 검증하고, 이상 감지시 자격 박탈

zookeeper

  • Cordinator로써 Kafka가 HA구성 할 수 있게 만들어준다.
    1. 서버의 상태를 감지한다
    2. Topic의 생성/소비 상태를 저장
    3. Kafka Cluser(Broker,partition…)의 Leader 선출

KRaft

  • Kafka에서 Zookeeper을 사용하지 않고 자체적으로 구동하기 위한 모드
  • 설정 방법
    • Zookeeper을 미설정하면된다.
    • Zookeeper의 역할을 Controller가 수행한다
  • 최근 버전에는 HA 구성을 위한 자체 Cordinator인 Kraft를 지원하는 것을 볼 수 있는데, 2023-09-23일 기준으로는 공식 홈페이지에도 TEST용도로는 좋지만, 배포는 하지 말라고 적혀있다
    • 결합 모드에서는 브로커와 별도로 컨트롤러를 롤링하거나 확장할 수 없음
    • 배포 환경에서는 결합 모드가 권장되지 않음

기본 설정

zookeeper.connect=[list of ZooKeeper servers]

# Log configuration
num.partitions=8
default.replication.factor=3
log.dir=[List of directories. Kafka should have its own dedicated disk(s) or SSD(s).]

# Other configurations
broker.id=[An integer. Start with 0 and increment by 1 for each new broker.]
listeners=[list of listeners]
auto.create.topics.enable=false
min.insync.replicas=2
queued.max.requests=[number of concurrent requests]
  • java 설정
    -Xmx6g -Xms6g -XX:MetaspaceSize=96m -XX:+UseG1GC
    -XX:MaxGCPauseMillis=20 -XX:InitiatingHeapOccupancyPercent=35 -XX:G1HeapRegionSize=16M
    -XX:MinMetaspaceFreeRatio=50 -XX:MaxMetaspaceFreeRatio=80 -XX:+ExplicitGCInvokesConcurrent
  • 하드웨어 ( 권장 사항 )
    • 24GB Memory, 8 cores 이상

개인적으로 공부한 내용 포스팅 중
잘못된 정보는 지적해주시면 좋겠습니다!

+ Recent posts